重构结构

This commit is contained in:
tursom 2019-12-02 02:06:20 +08:00
parent f3ac61c346
commit d008daef2d
8 changed files with 121 additions and 85 deletions

View File

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

View File

@ -1,4 +1,4 @@
dependencies { dependencies {
implementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.3.61' implementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.3.61'
compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '1.7.29' api group: 'org.slf4j', name: 'slf4j-api', version: '1.7.29'
} }

View File

@ -161,7 +161,7 @@ class StringRadixTree<T> {
return null return null
} }
fun listGet(route: String): List<Pair<T?, Int>>? { fun listGet(route: String): List<Pair<T?, Int>> {
val context = Context(route) val context = Context(route)
var node: Node<T>? = root var node: Node<T>? = root
val result = ArrayList<Pair<T?, Int>>() val result = ArrayList<Pair<T?, Int>>()
@ -272,15 +272,18 @@ class StringRadixTree<T> {
// println() // println()
// } // }
// //
// list.forEach { // println(listOf<String>().last())
// tree[it] = null // println(tree.listGet("roman"))
// println(tree)
// println()
// }
// //
// list.forEachIndexed { index, s -> // //list.forEach {
// tree[s] = index + 1 // // tree[it] = null
// println(tree) // // println(tree)
// println() // // println()
// } // //}
// //
// //list.forEachIndexed { index, s ->
// // tree[s] = index + 1
// // println(tree)
// // println()
// //}
//} //}

View File

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

View File

@ -1,7 +1,7 @@
package cn.tursom.web.netty package cn.tursom.web.netty
import cn.tursom.core.buffer.ByteBuffer import cn.tursom.core.buffer.ByteBuffer
import cn.tursom.web.AdvanceHttpContent import cn.tursom.web.MutableHttpContent
import cn.tursom.web.utils.Chunked import cn.tursom.web.utils.Chunked
import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBuf
import io.netty.buffer.CompositeByteBuf import io.netty.buffer.CompositeByteBuf
@ -17,7 +17,7 @@ import kotlin.collections.set
open class NettyHttpContent( open class NettyHttpContent(
val ctx: ChannelHandlerContext, val ctx: ChannelHandlerContext,
val msg: FullHttpRequest val msg: FullHttpRequest
) : AdvanceHttpContent, NettyResponseHeaderAdapter() { ) : MutableHttpContent, NettyResponseHeaderAdapter() {
override var finished: Boolean = false override var finished: Boolean = false
override val uri: String by lazy { override val uri: String by lazy {
var uri = msg.uri() var uri = msg.uri()

View File

@ -1,5 +1,5 @@
package cn.tursom.web package cn.tursom.web
interface AdvanceHttpContent : HttpContent { interface MutableHttpContent : HttpContent {
fun addParam(key: String, value: String) fun addParam(key: String, value: String)
} }

View File

@ -5,6 +5,7 @@ import cn.tursom.json.JsonWorkerImpl
import cn.tursom.web.ExceptionContent import cn.tursom.web.ExceptionContent
import cn.tursom.web.HttpContent import cn.tursom.web.HttpContent
import cn.tursom.web.HttpHandler import cn.tursom.web.HttpHandler
import cn.tursom.web.MutableHttpContent
import cn.tursom.web.router.impl.SimpleRouter import cn.tursom.web.router.impl.SimpleRouter
import cn.tursom.web.mapping.* import cn.tursom.web.mapping.*
import cn.tursom.web.result.Html import cn.tursom.web.result.Html
@ -24,21 +25,25 @@ import java.lang.reflect.Method
* 如果加了 @Mapping 注解会依据注解提供的路由路径注册 * 如果加了 @Mapping 注解会依据注解提供的路由路径注册
*/ */
@Suppress("MemberVisibilityCanBePrivate", "unused") @Suppress("MemberVisibilityCanBePrivate", "unused")
open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>( open class RoutedHttpHandler(
target: Any? = null, target: Any? = null,
val routerMaker: () -> Router<(T) -> Unit> = { SimpleRouter() } val routerMaker: () -> Router<(HttpContent) -> Unit> = { SimpleRouter() }
) : HttpHandler<T, E> { ) : HttpHandler<HttpContent, ExceptionContent> {
protected val router: Router<(T) -> Unit> = routerMaker() protected val router: Router<(HttpContent) -> Unit> = routerMaker()
protected val routerMap: HashMap<String, Router<(T) -> Unit>> = HashMap() protected val routerMap: HashMap<String, Router<(HttpContent) -> Unit>> = HashMap()
init { init {
@Suppress("LeakingThis") @Suppress("LeakingThis")
addRouter(target ?: this) addRouter(target ?: this)
} }
override fun handle(content: T) = handle(content, getHandler(content.method, content.uri)) override fun handle(content: HttpContent) = if (content is MutableHttpContent) {
handle(content, getHandler(content, content.method, content.uri))
} else {
handle(content, getHandler(content.method, content.uri).first)
}
open fun handle(content: T, handler: ((T) -> Unit)?) { open fun handle(content: HttpContent, handler: ((HttpContent) -> Unit)?) {
if (handler != null) { if (handler != null) {
handler(content) handler(content)
} else { } else {
@ -46,7 +51,7 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
} }
} }
open fun notFound(content: T) { open fun notFound(content: HttpContent) {
content.finish(404) content.finish(404)
} }
@ -64,16 +69,28 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
} }
} }
fun addRouter(route: String, handler: (T) -> Unit) { fun addRouter(route: String, handler: (HttpContent) -> Unit) {
router[safeRoute(route)] = handler router[safeRoute(route)] = handler
} }
fun addRouter(method: String, route: String, handler: (T) -> Unit) { fun addRouter(method: String, route: String, handler: (HttpContent) -> Unit) {
getRouter(method)[safeRoute(route)] = handler getRouter(method)[safeRoute(route)] = handler
} }
fun getHandler(method: String, route: String): ((T) -> Unit)? = fun getHandler(content: MutableHttpContent, method: String, route: String): ((HttpContent) -> Unit)? {
getRouter(method)[route].first ?: this.router[route].first val router = getHandler(method, route)
if (router.first != null) {
router.second.forEach { (k, v) ->
content.addParam(k, v)
}
}
return router.first ?: this.router[route].first
}
fun getHandler(method: String, route: String): Pair<((HttpContent) -> Unit)?, List<Pair<String, String>>> {
val router = getRouter(method)[route]
return if (router.first != null) router else this.router[route]
}
fun deleteRouter(route: String, method: String) { fun deleteRouter(route: String, method: String) {
getRouter(method).delRoute(safeRoute(route)) getRouter(method).delRoute(safeRoute(route))
@ -82,7 +99,7 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
protected fun insertMapping(obj: Any, method: Method) { protected fun insertMapping(obj: Any, method: Method) {
method.annotations.forEach { annotation -> method.annotations.forEach { annotation ->
val routes: Array<out String> val routes: Array<out String>
val router: Router<(T) -> Unit> val router: Router<(HttpContent) -> Unit>
when (annotation) { when (annotation) {
is Mapping -> { is Mapping -> {
routes = annotation.route routes = annotation.route
@ -148,7 +165,7 @@ open class RoutedHttpHandler<T : HttpContent, in E : ExceptionContent>(
} }
} }
protected fun getRouter(method: String): Router<(T) -> Unit> = when { protected fun getRouter(method: String): Router<(HttpContent) -> Unit> = when {
method.isEmpty() -> router method.isEmpty() -> router
else -> { else -> {
val upperCaseMethod = method.toUpperCase() val upperCaseMethod = method.toUpperCase()

View File

@ -1,81 +1,97 @@
package cn.tursom.web.router.impl package cn.tursom.web.router.impl
import cn.tursom.core.datastruct.StringRadixTree
import cn.tursom.web.router.Router import cn.tursom.web.router.Router
/** /**
* 匹配类似 * 匹配类似
* /java/{mod} * /java/:mod
* /java/{mod}/{id} * /java/:mod/:id
* /java/a{mod}/id * 不支持在参数后加静态路径
* /java/a{mod}_i/id
*/ */
class CurlyBracesRouter<T> : Router<T> { class CurlyBracesRouter<T> : Router<T> {
override fun addSubRoute(route: String, value: T?, onDestroy: ((oldValue: T) -> Unit)?) { private val router = StringRadixTree<Pair<T, List<String>>>()
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun delRoute(route: String) { override fun addSubRoute(route: String, value: T?, onDestroy: ((oldValue: T) -> Unit)?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates. TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
override fun get(route: String): Pair<T?, List<Pair<String, String>>> { override fun delRoute(route: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates. TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
override fun get(route: String): Pair<T?, List<Pair<String, String>>> {
val t = router.listGet(route)
if (t.isEmpty()) {
return null to listOf()
}
val pair = t.last()
if (pair.first == null || pair.second != route.length) {
return null to listOf()
}
val list = ArrayList<Pair<String, String>>()
pair.first!!.second.forEach {
}
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
} }
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
class RouteContext( class RouteContext(
val nodeList: List<String>, val nodeList: List<String>,
var location: Int = 0 var location: Int = 0
) { ) {
constructor(route: String) : this(route.substringBefore('?').split('/').filter { it.isNotEmpty() }) constructor(route: String) : this(route.substringBefore('?').split('/').filter { it.isNotEmpty() })
val remain get() = nodeList.size - location val remain get() = nodeList.size - location
val peek get() = nodeList[location] val peek get() = nodeList[location]
val copy get() = RouteContext(nodeList, location) val copy get() = RouteContext(nodeList, location)
fun increase(size: Int) { fun increase(size: Int) {
location += size location += size
} }
fun reset() { fun reset() {
location = 0 location = 0
} }
} }
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
class NodeContext(val nodeList: List<String>, val location: Int = 0) { class NodeContext(val nodeList: List<String>, val location: Int = 0) {
val remain get() = nodeList.size - location val remain get() = nodeList.size - location
val peek get() = nodeList[location] val peek get() = nodeList[location]
val route get() = RouteContext(nodeList, location) val route get() = RouteContext(nodeList, location)
} }
interface ICurlyBracesNode { interface ICurlyBracesNode {
val deep: Int val deep: Int
/** /**
* 用来对路径进行匹配与获得参数 * 用来对路径进行匹配与获得参数
*/ */
fun matchesAndParse(context: RouteContext, paramList: MutableList<Pair<String, String>>): Boolean fun matchesAndParse(context: RouteContext, paramList: MutableList<Pair<String, String>>): Boolean
fun matchesAndParse(context: RouteContext): List<Pair<String, String>>? { fun matchesAndParse(context: RouteContext): List<Pair<String, String>>? {
val list = ArrayList<Pair<String, String>>() val list = ArrayList<Pair<String, String>>()
return if (matchesAndParse(context, list)) { return if (matchesAndParse(context, list as MutableList<Pair<String, String>>)) {
list list
} else { } else {
null null
} }
} }
} }
class CurlyBracesNode(private val nodeContext: NodeContext) : ICurlyBracesNode { class CurlyBracesNode(private val nodeContext: NodeContext) : ICurlyBracesNode {
override val deep: Int get() = 1 override val deep: Int get() = 1
override fun matchesAndParse(context: RouteContext, paramList: MutableList<Pair<String, String>>): Boolean { override fun matchesAndParse(context: RouteContext, paramList: MutableList<Pair<String, String>>): Boolean {
return if (nodeContext.peek == context.peek) { return if (nodeContext.peek == context.peek) {
context.increase(1) context.increase(1)
true true
} else { } else {
false false
} }
} }
} }
class PlaceholderCurlyBracesNode class PlaceholderCurlyBracesNode