修复 AsyncRoutedHttpHandler 的删除路径功能

This commit is contained in:
tursom 2019-12-14 22:56:07 +08:00
parent b3313f030d
commit 5f1f116b39
2 changed files with 58 additions and 11 deletions

View File

@ -61,12 +61,12 @@ open class RoutedHttpHandler(
@Suppress("LeakingThis") @Suppress("LeakingThis")
val clazz = handler.javaClass val clazz = handler.javaClass
clazz.methods.forEach { method -> clazz.methods.forEach { method ->
log?.debug("try mapping {}({})", method, method.parameterTypes)
method.parameterTypes.let { method.parameterTypes.let {
if (!(it.size == 1 && HttpContent::class.java.isAssignableFrom(it[0])) && it.isNotEmpty()) { if (!(it.size == 1 && HttpContent::class.java.isAssignableFrom(it[0])) && it.isNotEmpty()) {
return@forEach return@forEach
} }
} }
log?.debug("mapping {} {}", method, method.parameterTypes)
insertMapping(handler, method) insertMapping(handler, method)
} }
} }
@ -108,8 +108,7 @@ open class RoutedHttpHandler(
if (mapping.isEmpty()) { if (mapping.isEmpty()) {
addRouter(obj, method, route, router) addRouter(obj, method, route, router)
} else mapping.forEach { } else mapping.forEach {
val base = safeRoute(it) addRouter(obj, method, safeRoute(it) + route, router)
addRouter(obj, method, base + route, router)
} }
} }
} }
@ -156,7 +155,7 @@ open class RoutedHttpHandler(
getRouter(method).delRoute(safeRoute(route)) getRouter(method).delRoute(safeRoute(route))
} }
fun deleteRouter(handler: Any) { open fun deleteRouter(handler: Any) {
@Suppress("LeakingThis") @Suppress("LeakingThis")
val clazz = handler.javaClass val clazz = handler.javaClass
clazz.methods.forEach { method -> clazz.methods.forEach { method ->
@ -171,18 +170,27 @@ open class RoutedHttpHandler(
} }
protected fun deleteMapping(obj: Any, method: Method) { protected fun deleteMapping(obj: Any, method: Method) {
val mapping = obj::class.java.getAnnotation(Mapping::class.java)?.route ?: arrayOf("")
method.annotations.forEach { annotation -> method.annotations.forEach { annotation ->
val (routes, router) = getRoutes(annotation) ?: return@forEach val (routes, router) = getRoutes(annotation) ?: return@forEach
routes.forEach { route -> routes.forEach { route ->
log?.info("delete route {} mapped to {}", route, method) log?.info("delete route {} mapped to {}", route, method)
val handler = router[safeRoute(route)].first if (mapping.isEmpty()) {
if (handler?.first == obj) { deleteMapping(obj, route, router)
router.delRoute(safeRoute(route)) } else mapping.forEach {
deleteMapping(obj, safeRoute(it) + route, router)
} }
} }
} }
} }
protected fun deleteMapping(obj: Any, route: String, router: Router<Pair<Any?, (HttpContent) -> Unit>>) {
val handler = router[safeRoute(route)].first
if (handler?.first == obj) {
router.delRoute(safeRoute(route))
}
}
protected fun getRoutes(annotation: Annotation) = when (annotation) { protected fun getRoutes(annotation: Annotation) = when (annotation) {
is Mapping -> { is Mapping -> {
annotation.route to getRouter(annotation.method) annotation.route to getRouter(annotation.method)
@ -258,8 +266,9 @@ open class RoutedHttpHandler(
if (it.endsWith('/')) it.dropLast(1) else it if (it.endsWith('/')) it.dropLast(1) else it
}.repeatUntil({ it.contains("//") }) { it.replace(slashRegex, "/") } }.repeatUntil({ it.contains("//") }) { it.replace(slashRegex, "/") }
fun autoReturn(result: Any, content: HttpContent) { fun autoReturn(result: Any?, content: HttpContent) {
log?.debug("{}: autoReturn: {}", content.clientIp, result) log?.debug("{}: autoReturn: {}", content.clientIp, result)
result ?: return
when (result) { when (result) {
is String -> content.finishText(result.toByteArray()) is String -> content.finishText(result.toByteArray())
is StringBuilder -> content.finishText(result.toString().toByteArray()) is StringBuilder -> content.finishText(result.toString().toByteArray())
@ -277,8 +286,9 @@ open class RoutedHttpHandler(
} }
} }
fun finishHtml(result: Any, content: HttpContent) { fun finishHtml(result: Any?, content: HttpContent) {
log?.debug("{}: finishHtml: {}", content.clientIp, result) log?.debug("{}: finishHtml: {}", content.clientIp, result)
result ?: return
when (result) { when (result) {
is ByteBuffer -> content.finishHtml(result) is ByteBuffer -> content.finishHtml(result)
is ByteArray -> content.finishHtml(result) is ByteArray -> content.finishHtml(result)
@ -287,8 +297,9 @@ open class RoutedHttpHandler(
} }
} }
fun finishText(result: Any, content: HttpContent) { fun finishText(result: Any?, content: HttpContent) {
log?.debug("{}: finishText: {}", content.clientIp, result) log?.debug("{}: finishText: {}", content.clientIp, result)
result ?: return
when (result) { when (result) {
is ByteBuffer -> content.finishText(result) is ByteBuffer -> content.finishText(result)
is ByteArray -> content.finishText(result) is ByteArray -> content.finishText(result)
@ -297,8 +308,9 @@ open class RoutedHttpHandler(
} }
} }
fun finishJson(result: Any, content: HttpContent) { fun finishJson(result: Any?, content: HttpContent) {
log?.debug("{}: finishJson: {}", content.clientIp, result) log?.debug("{}: finishJson: {}", content.clientIp, result)
result ?: return
when (result) { when (result) {
is ByteBuffer -> content.finishJson(result) is ByteBuffer -> content.finishJson(result)
is ByteArray -> content.finishJson(result) is ByteArray -> content.finishJson(result)

View File

@ -75,6 +75,7 @@ open class AsyncRoutedHttpHandler(
return@forEach return@forEach
} }
} }
log?.debug("mapping {} {}", member, member.parameters)
insertMapping(handler, member) insertMapping(handler, member)
} }
} }
@ -184,6 +185,40 @@ open class AsyncRoutedHttpHandler(
} }
} }
override fun deleteRouter(handler: Any) {
super.deleteRouter(handler)
handler::class.members.forEach { member ->
if (member.isSuspend) {
member.parameters.let {
if (it.size != 1 && !(it.size == 2 && HttpContent::class.java.isAssignableFrom(it[1].type.jvmErasure.java))) {
return@forEach
}
}
val mapping = handler::class.java.getAnnotation(Mapping::class.java)?.route ?: arrayOf("")
member.annotations.forEach { annotation ->
val (routes, router) = getAsyncRoutes(annotation) ?: return@forEach
@Suppress("DuplicatedCode")
routes.forEach { route ->
if (mapping.isEmpty()) {
deleteRouter(handler, route, router)
} else mapping.forEach {
val base = safeRoute(it)
deleteRouter(handler, base + route, router)
}
}
}
}
}
}
fun deleteRouter(handler: Any, route: String, router: Router<Pair<Any?, suspend (HttpContent) -> Unit>>) {
val (pair, _) = router[route]
val (target, _) = pair ?: return
if (handler == target) {
router.delRoute(route)
}
}
companion object { companion object {
private val log = try { private val log = try {
LoggerFactory.getLogger(RoutedHttpHandler::class.java) LoggerFactory.getLogger(RoutedHttpHandler::class.java)