mirror of
https://github.com/tursom/TursomServer.git
synced 2025-02-03 16:20:16 +08:00
添加http返回类型枚举
This commit is contained in:
parent
85291d9f59
commit
1f9372ae68
@ -14,6 +14,7 @@ import cn.tursom.web.result.Text
|
||||
import cn.tursom.web.router.impl.SimpleRouter
|
||||
import cn.tursom.web.utils.Chunked
|
||||
import cn.tursom.web.utils.ContextType
|
||||
import cn.tursom.web.utils.NoReturnLog
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
@ -55,7 +56,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
override fun handle(content: HttpContent) {
|
||||
log?.debug("{}: {} {}", content.clientIp, content.method, content.uri)
|
||||
log?.debug("{} {} {}", content.clientIp, content.method, content.uri)
|
||||
if (content is MutableHttpContent) {
|
||||
handle(content, getHandler(content, content.method, content.uri))
|
||||
} else {
|
||||
@ -132,19 +133,20 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
fun addRouter(obj: Any, method: Method, route: String, router: Router<Pair<Any?, (HttpContent) -> Any?>>) {
|
||||
val doLog = method.doLog
|
||||
router[safeRoute(route)] = obj to (if (method.parameterTypes.isEmpty()) {
|
||||
when {
|
||||
method.getAnnotation(Html::class.java) != null -> { content ->
|
||||
method(obj)?.let { result -> finishHtml(result, content) }
|
||||
method(obj)?.let { result -> finishHtml(result, content, doLog) }
|
||||
}
|
||||
method.getAnnotation(Text::class.java) != null -> { content ->
|
||||
method(obj)?.let { result -> finishText(result, content) }
|
||||
method(obj)?.let { result -> finishText(result, content, doLog) }
|
||||
}
|
||||
method.getAnnotation(Json::class.java) != null -> { content ->
|
||||
method(obj)?.let { result -> finishJson(result, content) }
|
||||
method(obj)?.let { result -> finishJson(result, content, doLog) }
|
||||
}
|
||||
else -> { content ->
|
||||
method(obj)?.let { result -> autoReturn(method, result, content) }
|
||||
method(obj)?.let { result -> autoReturn(method, result, content, doLog) }
|
||||
}
|
||||
}
|
||||
} else when (method.returnType) {
|
||||
@ -153,16 +155,16 @@ open class RoutedHttpHandler(
|
||||
Unit::class.java -> { content -> method(obj, content) }
|
||||
else -> when {
|
||||
method.getAnnotation(Html::class.java) != null -> { content ->
|
||||
method(obj, content)?.let { result -> finishHtml(result, content) }
|
||||
method(obj, content)?.let { result -> finishHtml(result, content, doLog) }
|
||||
}
|
||||
method.getAnnotation(Text::class.java) != null -> { content ->
|
||||
method(obj, content)?.let { result -> finishText(result, content) }
|
||||
method(obj, content)?.let { result -> finishText(result, content, doLog) }
|
||||
}
|
||||
method.getAnnotation(Json::class.java) != null -> { content ->
|
||||
method(obj, content)?.let { result -> finishJson(result, content) }
|
||||
method(obj, content)?.let { result -> finishJson(result, content, doLog) }
|
||||
}
|
||||
else -> { content: HttpContent ->
|
||||
method(obj, content)?.let { result -> autoReturn(method, result, content) }
|
||||
method(obj, content)?.let { result -> autoReturn(method, result, content, doLog) }
|
||||
}
|
||||
}
|
||||
}).let {
|
||||
@ -273,6 +275,8 @@ open class RoutedHttpHandler(
|
||||
null
|
||||
}
|
||||
|
||||
val Method.doLog get() = getAnnotation(NoReturnLog::class.java) == null
|
||||
|
||||
fun <T> T.repeatUntil(state: (T) -> Boolean, block: (T) -> T): T {
|
||||
var result = this
|
||||
while (state(result)) {
|
||||
@ -288,15 +292,16 @@ open class RoutedHttpHandler(
|
||||
if (it.endsWith('/')) it.dropLast(1) else it
|
||||
}.repeatUntil({ it.contains("//") }) { it.replace(slashRegex, "/") }
|
||||
|
||||
fun autoReturn(method: Method, result: Any?, content: HttpContent) {
|
||||
fun autoReturn(method: Method, result: Any?, content: HttpContent, doLog: Boolean? = null) {
|
||||
method.getAnnotation(ContextType::class.java)?.let {
|
||||
content.autoContextType(it.type)
|
||||
content.setContextType(it.type.value)
|
||||
log?.debug("{}: autoReturn context type auto set to {}({})", content.clientIp, it.type.key, it.type.value)
|
||||
}
|
||||
autoReturn(result, content)
|
||||
autoReturn(result, content, doLog ?: method.doLog)
|
||||
}
|
||||
|
||||
fun autoReturn(result: Any?, content: HttpContent) {
|
||||
log?.debug("{}: autoReturn: {}", content.clientIp, result)
|
||||
fun autoReturn(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: autoReturn: {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is String -> content.finishText(result.toByteArray())
|
||||
@ -315,8 +320,8 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun finishHtml(result: Any?, content: HttpContent) {
|
||||
log?.debug("{}: finishHtml: {}", content.clientIp, result)
|
||||
fun finishHtml(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: finishHtml: {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is ByteBuffer -> content.finishHtml(result)
|
||||
@ -332,8 +337,8 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun finishText(result: Any?, content: HttpContent) {
|
||||
log?.debug("{}: finishText: {}", content.clientIp, result)
|
||||
fun finishText(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: finishText: {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is ByteBuffer -> content.finishText(result)
|
||||
@ -349,8 +354,8 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun finishJson(result: Any?, content: HttpContent) {
|
||||
log?.debug("{}: finishJson: {}", content.clientIp, result)
|
||||
fun finishJson(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: finishJson: {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is ByteBuffer -> content.finishJson(result)
|
||||
@ -365,7 +370,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
else -> {
|
||||
val json = json?.toJson(result)
|
||||
log?.debug("{}: finishJson: generate json: {}", content.clientIp, json)
|
||||
if (doLog) log?.debug("{}: finishJson: generate json: {}", content.clientIp, json)
|
||||
if (json != null) {
|
||||
content.finishJson(json.toByteArray())
|
||||
} else {
|
||||
|
@ -1,3 +1,3 @@
|
||||
package cn.tursom.web.utils
|
||||
|
||||
annotation class ContextType(val type: String)
|
||||
annotation class ContextType(val type: ContextTypeEnum)
|
160
web/src/main/kotlin/cn/tursom/web/utils/ContextTypeEnum.kt
Normal file
160
web/src/main/kotlin/cn/tursom/web/utils/ContextTypeEnum.kt
Normal file
@ -0,0 +1,160 @@
|
||||
package cn.tursom.web.utils
|
||||
|
||||
import cn.tursom.core.datastruct.StringRadixTree
|
||||
|
||||
@Suppress("EnumEntryName", "unused", "SpellCheckingInspection")
|
||||
enum class ContextTypeEnum(val key: String, val value: String) {
|
||||
aac("aac", "audio/aac"),
|
||||
abw("abw", "application/x-abiword"),
|
||||
arc("arc", "application/x-freearc"),
|
||||
avi("avi", "video/x-msvideo"),
|
||||
azw("azw", "aapplication/vnd.amazon.ebook"),
|
||||
bin("bin", "application/octet-stream"),
|
||||
bmp("bmp", "image/bmp"),
|
||||
bz("bz", "application/x-bzip"),
|
||||
bz2("bz2", "application/x-bzip2"),
|
||||
csh("csh", "application/x-csh"),
|
||||
css("css", "itext/css; charset=UTF-8"),
|
||||
csv("csv", "itext/csv; charset=UTF-8"),
|
||||
doc("doc", "application/msword"),
|
||||
docx("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
|
||||
eot("eot", "application/vnd.ms-fontobject"),
|
||||
epub("epub", "application/epub+zip"),
|
||||
gif("gif", "image/gif"),
|
||||
html("html", "text/html; charset=UTF-8"),
|
||||
htm("htm", "text/html; charset=UTF-8"),
|
||||
ico("ico", "image/vnd.microsoft.icon"),
|
||||
ics("ics", "text/calendar; charset=UTF-8"),
|
||||
jar("jar", "application/java-archive"),
|
||||
jpeg("jpeg", "image/jpeg"),
|
||||
jpg("jpg", "image/jpeg"),
|
||||
js("js", "text/javascript; charset=UTF-8"),
|
||||
json("json", "application/json; charset=UTF-8"),
|
||||
jsonld("jsonld", "application/ld+json"),
|
||||
mid("mid", "audio/midi"),
|
||||
midi("midi", "audio/midi"),
|
||||
mjs("mjs", "text/javascript"),
|
||||
mp3("mp3", "audio/mpeg"),
|
||||
mp4("mp4", "audio/mp4"),
|
||||
mpeg("mpeg", "video/mpeg"),
|
||||
mpkg("mpkg", "application/vnd.apple.installer+xml"),
|
||||
odp("odp", "application/vnd.oasis.opendocument.presentation"),
|
||||
ods("ods", "application/vnd.oasis.opendocument.spreadsheet"),
|
||||
odt("odt", "application/vnd.oasis.opendocument.text"),
|
||||
oga("oga", "audio/ogg"),
|
||||
ogg("ogg", "application/ogg"),
|
||||
ogv("ogv", "video/ogg"),
|
||||
ogx("ogx", "application/ogg"),
|
||||
otf("otf", "font/otf"),
|
||||
png("png", "image/png"),
|
||||
pdf("pdf", "application/pdf"),
|
||||
ppt("ppt", "application/vnd.ms-powerpoint"),
|
||||
pptx("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"),
|
||||
rar("rar", "application/x-rar-compressed"),
|
||||
rtf("rtf", "application/rtf"),
|
||||
sh("sh", "application/x-sh"),
|
||||
svg("svg", "image/svg+xml"),
|
||||
swf("swf", "application/x-shockwave-flash"),
|
||||
tar("tar", "application/x-tar"),
|
||||
tif("tif", "image/tiff"),
|
||||
tiff("tiff", "image/tiff"),
|
||||
ttf("ttf", "font/ttf"),
|
||||
txt("txt", "text/plain; charset=UTF-8"),
|
||||
vsd("vsd", "application/vnd.visio"),
|
||||
wav("wav", "audio/wav"),
|
||||
weba("weba", "audio/webm"),
|
||||
webm("webm", "video/webm"),
|
||||
webp("webp", "image/webp"),
|
||||
woff("woff", "font/woff"),
|
||||
woff2("woff2", "font/woff2"),
|
||||
xhtml("xhtml", "application/xhtml+xml"),
|
||||
xls("xls", "application/vnd.ms-excel"),
|
||||
xlsx("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
|
||||
xml("xml", "text/xml; charset=UTF-8"),
|
||||
xul("xul", "application/vnd.mozilla.xul+xml"),
|
||||
zip("zip", "application/zip"),
|
||||
`3gp`("3gp", "video/3gpp"),
|
||||
`3g2`("3g2", "ivideo/3gpp2"),
|
||||
`7z`("7z", "application/x-7z-compressed");
|
||||
|
||||
companion object {
|
||||
private val router = StringRadixTree<ContextTypeEnum>()
|
||||
|
||||
init {
|
||||
router["aac"] = aac
|
||||
router["abw"] = abw
|
||||
router["arc"] = arc
|
||||
router["avi"] = avi
|
||||
router["azw"] = azw
|
||||
router["bin"] = bin
|
||||
router["bmp"] = bmp
|
||||
router["bz"] = bz
|
||||
router["bz2"] = bz2
|
||||
router["csh"] = csh
|
||||
router["css"] = css
|
||||
router["csv"] = csv
|
||||
router["doc"] = doc
|
||||
router["docx"] = docx
|
||||
router["eot"] = eot
|
||||
router["epub"] = epub
|
||||
router["gif"] = gif
|
||||
router["html"] = html
|
||||
router["htm"] = htm
|
||||
router["ico"] = ico
|
||||
router["ics"] = ics
|
||||
router["jar"] = jar
|
||||
router["jpeg"] = jpeg
|
||||
router["jpg"] = jpg
|
||||
router["js"] = js
|
||||
router["json"] = json
|
||||
router["jsonld"] = jsonld
|
||||
router["mid"] = mid
|
||||
router["midi"] = midi
|
||||
router["mjs"] = mjs
|
||||
router["mp3"] = mp3
|
||||
router["mp4"] = mp4
|
||||
router["mpeg"] = mpeg
|
||||
router["mpkg"] = mpkg
|
||||
router["odp"] = odp
|
||||
router["ods"] = ods
|
||||
router["odt"] = odt
|
||||
router["oga"] = oga
|
||||
router["ogg"] = ogg
|
||||
router["ogv"] = ogv
|
||||
router["ogx"] = ogx
|
||||
router["otf"] = otf
|
||||
router["png"] = png
|
||||
router["pdf"] = pdf
|
||||
router["ppt"] = ppt
|
||||
router["pptx"] = pptx
|
||||
router["rar"] = rar
|
||||
router["rtf"] = rtf
|
||||
router["sh"] = sh
|
||||
router["svg"] = svg
|
||||
router["swf"] = swf
|
||||
router["tar"] = tar
|
||||
router["tif"] = tif
|
||||
router["tiff"] = tiff
|
||||
router["ttf"] = ttf
|
||||
router["txt"] = txt
|
||||
router["vsd"] = vsd
|
||||
router["wav"] = wav
|
||||
router["weba"] = weba
|
||||
router["webm"] = webm
|
||||
router["webp"] = webp
|
||||
router["woff"] = woff
|
||||
router["woff2"] = woff2
|
||||
router["xhtml"] = xhtml
|
||||
router["xls"] = xls
|
||||
router["xlsx"] = xlsx
|
||||
router["xml"] = xml
|
||||
router["xul"] = xul
|
||||
router["zip"] = zip
|
||||
router["3gp"] = `3gp`
|
||||
router["3g2"] = `3g2`
|
||||
router["7z"] = `7z`
|
||||
}
|
||||
|
||||
operator fun get(value: String) = router[value] ?: throw IllegalAccessException()
|
||||
}
|
||||
}
|
@ -80,4 +80,6 @@ object ContextTypeMap {
|
||||
router["3g2"] = "ivideo/3gpp2"
|
||||
router["7z"] = "application/x-7z-compressed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
3
web/src/main/kotlin/cn/tursom/web/utils/NoReturnLog.kt
Normal file
3
web/src/main/kotlin/cn/tursom/web/utils/NoReturnLog.kt
Normal file
@ -0,0 +1,3 @@
|
||||
package cn.tursom.web.utils
|
||||
|
||||
annotation class NoReturnLog
|
@ -8,10 +8,10 @@ import cn.tursom.web.result.Json
|
||||
import cn.tursom.web.result.Text
|
||||
import cn.tursom.web.router.impl.SimpleRouter
|
||||
import cn.tursom.web.utils.ContextType
|
||||
import cn.tursom.web.utils.NoReturnLog
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.jvm.jvmErasure
|
||||
@ -26,7 +26,7 @@ open class AsyncRoutedHttpHandler(
|
||||
protected val asyncRouterMap: HashMap<String, Router<Pair<Any?, suspend (HttpContent) -> Unit>>> = HashMap()
|
||||
|
||||
override fun handle(content: HttpContent) {
|
||||
log?.debug("{}: {} {}", content.clientIp, content.method, content.uri)
|
||||
log?.debug("{} {} {}", content.clientIp, content.method, content.uri)
|
||||
if (content is MutableHttpContent) {
|
||||
val handler = getAsyncHandler(content, content.method, content.uri)
|
||||
if (handler != null) GlobalScope.launch {
|
||||
@ -103,19 +103,20 @@ open class AsyncRoutedHttpHandler(
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun addRouter(obj: Any, method: KCallable<*>, route: String, router: Router<Pair<Any?, suspend (HttpContent) -> Unit>>) {
|
||||
val doLog = method.doLog
|
||||
router[safeRoute(route)] = if (method.parameters.size == 1) {
|
||||
obj to when {
|
||||
method.findAnnotation<Html>() != null -> { content ->
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishHtml(result, content) }
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishHtml(result, content, doLog) }
|
||||
}
|
||||
method.findAnnotation<Text>() != null -> { content ->
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishText(result, content) }
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishText(result, content, doLog) }
|
||||
}
|
||||
method.findAnnotation<Json>() != null -> { content ->
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishJson(result, content) }
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishJson(result, content, doLog) }
|
||||
}
|
||||
else -> { content ->
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> autoReturn(method, result, content) }
|
||||
(method as suspend Any.() -> Any?)(obj)?.let { result -> autoReturn(method, result, content, doLog) }
|
||||
}
|
||||
}
|
||||
} else obj to when (method.returnType.jvmErasure.java) {
|
||||
@ -124,16 +125,16 @@ open class AsyncRoutedHttpHandler(
|
||||
Unit::class.java -> { content -> (method as suspend Any.(HttpContent) -> Unit)(obj, content) }
|
||||
else -> when {
|
||||
method.findAnnotation<Html>() != null -> { content ->
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishHtml(result, content) }
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishHtml(result, content, doLog) }
|
||||
}
|
||||
method.findAnnotation<Text>() != null -> { content ->
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishText(result, content) }
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishText(result, content, doLog) }
|
||||
}
|
||||
method.findAnnotation<Json>() != null -> { content ->
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishJson(result, content) }
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishJson(result, content, doLog) }
|
||||
}
|
||||
else -> { content ->
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> autoReturn(method, result, content) }
|
||||
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> autoReturn(method, result, content, doLog) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -229,11 +230,14 @@ open class AsyncRoutedHttpHandler(
|
||||
null
|
||||
}
|
||||
|
||||
fun autoReturn(method: KCallable<*>, result: Any?, content: HttpContent) {
|
||||
val KCallable<*>.doLog get() = findAnnotation<NoReturnLog>() == null
|
||||
|
||||
fun autoReturn(method: KCallable<*>, result: Any?, content: HttpContent, doLog: Boolean? = null) {
|
||||
method.findAnnotation<ContextType>()?.let {
|
||||
content.autoContextType(it.type)
|
||||
content.setContextType(it.type.value)
|
||||
log?.debug("{}: autoReturn context type auto set to {}({})", content.clientIp, it.type.key, it.type.value)
|
||||
}
|
||||
autoReturn(result, content)
|
||||
autoReturn(result, content, doLog ?: method.doLog)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user