一、WebFlux统一包装响应

   原创文章,转载请注明出处。

一、确认手术点

 
  根据官方介绍:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html,确定 ResponseBodyResultHandler 是处理由 @ResponseBody 注释的方法的,进一步 Debug 源码发现,其工作过程依赖 DispatcherHandler、及 WebFluxConfigurationSupport。因此,若想继承、扩展 ResponseBodyResultHandler,则不得不从头以 Spring Boot 方式覆盖 WebFluxConfigurationSupport 启动加载过程,这会有较多代码量,稍不留神还会改变框架默认行为。
 
  这里提供一种新的思路,以切面的方式 动态增强 ResponseBodyResultHandler,只需将类声明为 Bean,整个过程 一个方法就好。

二、切点、切面

   比较简单,使用了 AspectJ:

/**
 * Created by xuguangyuansh on 2019-09-01.
 */
@Configuration
@ConditionalOnClass(name = ["org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler"])
@Aspect
class AspectResponseBodyResultHandler {

    /**
     * 统一封装响应, Aop增强 ResponseBodyResultHandler.handleResult
     *
     * See: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
     */
    @Around("execution(* org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler.handleResult(..)) && args(exchange, result)")
    fun AroundHandleResult(pjp: ProceedingJoinPoint, exchange: ServerWebExchange, result: HandlerResult): Mono<*> {
        // Object handler, @Nullable Object returnValue, MethodParameter returnType, @Nullable BindingContext context
        result.apply {
            return returnValue?.let {
                val value = (returnValue as Mono<*>).map {
                    if (it !is Status)
                        Status.Ok(it)
                    else it
                }
                val handlerResult = HandlerResult(handler, value, returnTypeSource, bindingContext)
                return pjp.proceed(arrayOf(exchange, handlerResult)) as Mono<*>
            } ?: Mono.empty<Void>()
        }
    }
    
}

三、统一响应对象

/**
 * Created by xuguangyuansh on 2019-07-24.
 */
class Status {
    var code: Int = 10001
    var success: Boolean = true
    var msg: String? = null
    var data: Any? = null

    companion object {
        fun Ok() = Status()

        fun Ok(data: Any?): Status {
            return Status().apply {
                data?.let {
                    if (it is List<*>)
                        this.data = mapOf("list" to it)
                    else
                        this.data = it
                }
            }
        }

        fun BadRequest(msg: String?): Status {
            return Status().apply {
                this.msg = msg
                this.success = false
            }
        }
    }
}

   没啥说的,然后,已经没有然后了。

你可能感兴趣的:(《Spring,WebFlux》)