添加 json 工具类

This commit is contained in:
tursom 2019-11-30 14:06:25 +08:00
parent a7d6f4a211
commit fbabf71a3b
8 changed files with 76 additions and 10 deletions

6
json/build.gradle Normal file
View File

@ -0,0 +1,6 @@
dependencies {
compileOnly 'com.alibaba:fastjson:1.2.62'
compileOnly group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
compileOnly group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.10.1'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.1'
}

View File

@ -0,0 +1,6 @@
package cn.tursom.json
interface JsonWorker {
fun toJson(obj: Any): String?
fun <T> fromJson(json: String, clazz: Class<T>): T?
}

View File

@ -0,0 +1,23 @@
package cn.tursom.json
import com.fasterxml.jackson.databind.ObjectMapper
import com.google.gson.Gson
class JsonWorkerImpl : JsonWorker {
private val gson = try {
Gson()
} catch (e: Throwable) {
null
}
private val jackson = try {
ObjectMapper()
} catch (e: Throwable) {
null
}
override fun toJson(obj: Any): String? = gson?.toJson(obj) ?: jackson?.writeValueAsString(obj)
override fun <T> fromJson(json: String, clazz: Class<T>): T? =
gson?.fromJson(json, clazz) ?: jackson?.readValue(json, clazz)
}

View File

@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory
import kotlin.reflect.KClass
import kotlin.reflect.jvm.jvmName
class Slf4jImpl(name: String? = null) : Slf4j {
open class Slf4jImpl(name: String? = null) : Slf4j {
constructor(clazz: Class<*>?) : this(clazz?.name)
constructor(clazz: KClass<*>?) : this(clazz?.jvmName?.let {
if (clazz.isCompanion) it.dropLast(10) else it

View File

@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory
import kotlin.reflect.KClass
import kotlin.reflect.jvm.jvmName
class TrySlf4jImpl(name: String? = null) : TrySlf4j {
open class TrySlf4jImpl(name: String? = null) : TrySlf4j {
constructor(clazz: Class<*>?) : this(clazz?.name)
constructor(clazz: KClass<*>?) : this(clazz?.jvmName?.let {
if (clazz.isCompanion) it.dropLast(10) else it

View File

@ -3,4 +3,5 @@ include 'web', 'aop', 'database', 'database:database-async', 'utils', 'utils:xml
include 'socket', 'socket:socket-async'
include 'AsyncSocket'
include 'log'
include 'json'

View File

@ -1,4 +1,5 @@
dependencies {
implementation project(":")
compileOnly project(":json")
compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '1.7.29'
}

View File

@ -1,11 +1,15 @@
package cn.tursom.web.router
import cn.tursom.json.JsonWorkerImpl
import cn.tursom.web.ExceptionContent
import cn.tursom.web.HttpContent
import cn.tursom.web.HttpHandler
import cn.tursom.web.router.impl.SimpleRouter
import cn.tursom.web.router.mapping.*
import cn.tursom.web.utils.Chunked
import org.slf4j.LoggerFactory
import java.io.File
import java.io.RandomAccessFile
import java.lang.reflect.Method
/**
@ -20,8 +24,8 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
target: Any? = null,
val routerMaker: () -> Router<(T) -> Unit> = { SimpleRouter() }
) : HttpHandler<T, E> {
private val router: Router<(T) -> Unit> = routerMaker()
private val routerMap: HashMap<String, Router<(T) -> Unit>> = HashMap()
protected val router: Router<(T) -> Unit> = routerMaker()
protected val routerMap: HashMap<String, Router<(T) -> Unit>> = HashMap()
init {
@Suppress("LeakingThis")
@ -47,10 +51,13 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
val clazz = handler.javaClass
clazz.methods.forEach { method ->
method.parameterTypes.let {
if (it.size != 1 || !HttpContent::class.java.isAssignableFrom(it[0]))
if (it.size != 1 || !HttpContent::class.java.isAssignableFrom(it[0])) {
return@forEach
} else if (it.isNotEmpty()) {
return@forEach
}
}
insertMapping(method)
insertMapping(handler, method)
}
}
@ -69,7 +76,7 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
getRouter(method).delRoute(safeRoute(route))
}
private fun insertMapping(method: Method) {
protected fun insertMapping(obj: Any, method: Method) {
method.annotations.forEach { annotation ->
val routes: Array<out String>
val router: Router<(T) -> Unit>
@ -117,13 +124,29 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
else -> return@forEach
}
routes.forEach { route ->
log?.info("method {} mapped to route {}", method, route)
router[safeRoute(route)] = { content -> method(this, content) }
log?.info("method route {} mapped to {}", route, method)
router[safeRoute(route)] = handler@{ content ->
if (method.parameterTypes.isEmpty()) {
val result = method(obj) ?: return@handler
when (result) {
is String -> content.finishHtml(result.toByteArray())
is ByteArray -> content.finishText(result)
is File -> content.finishFile(result)
is RandomAccessFile -> content.finishFile(result)
is Chunked -> content.finishChunked(result)
else -> json?.let {
content.finishJson(json.toJson(result)!!.toByteArray())
} ?: content.finishText(result.toString().toByteArray())
}
} else {
method(obj, content)
}
}
}
}
}
private fun getRouter(method: String): Router<(T) -> Unit> = when {
protected fun getRouter(method: String): Router<(T) -> Unit> = when {
method.isEmpty() -> router
else -> {
val upperCaseMethod = method.toUpperCase()
@ -143,6 +166,12 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
null
}
private val json = try {
JsonWorkerImpl()
} catch (e: Throwable) {
null
}
private fun safeRoute(route: String) = if (route.first() == '/') route else "/$route"
}
}