文章目录 1.common-tool-starter 1.目录结构 2.ResultWrapper.java 2.common-web-starter 1.目录结构 2.IgnoredResultWrapper.java 自定义注解,忽略对返回结果的自动包装 3.ReturnValueHandlersDecorator.java 对适配器进行扩展的装饰器 4.WebAutoConfiguration.java 将装饰器注入容器 3.common-web-starter-demo 1.WebController.java 测试三种使用方式 2.测试 1.第一种:直接使用自动包装成功结果 2.第二种:使用 @IgnoredResultWrapper注解忽略掉自动包装 3.第三种:直接使用ResultWrapper来自己封装结果
1.common-tool-starter
1.目录结构
2.ResultWrapper.java
package com. sunxiansheng. tool. response ; import lombok. Data ; import java. io. Serializable ;
@Data
public class ResultWrapper < T > implements Serializable { private static final long serialVersionUID = 1L ; private boolean success; private int code; private String message; private T data; private ResultWrapper ( ) { } public static class Builder < T > { private boolean success; private int code; private String message; private T data; public Builder < T > success ( boolean success) { this . success = success; return this ; } public Builder < T > code ( int code) { this . code = code; return this ; } public Builder < T > message ( String message) { this . message = message; return this ; } public Builder < T > data ( T data) { this . data = data; return this ; } public ResultWrapper < T > build ( ) { ResultWrapper < T > result = new ResultWrapper < > ( ) ; result. success = this . success; result. code = this . code; result. message = this . message; result. data = this . data; return result; } } public static < T > ResultWrapper < T > ok ( ) { return new Builder < T > ( ) . success ( true ) . code ( RespBeanEnum . SUCCESS . getCode ( ) ) . message ( RespBeanEnum . SUCCESS . getMessage ( ) ) . build ( ) ; } public static < T > ResultWrapper < T > ok ( T data) { return new Builder < T > ( ) . success ( true ) . code ( RespBeanEnum . SUCCESS . getCode ( ) ) . message ( RespBeanEnum . SUCCESS . getMessage ( ) ) . data ( data) . build ( ) ; } public static < T > ResultWrapper < T > ok ( T data, String message) { return new Builder < T > ( ) . success ( true ) . code ( RespBeanEnum . SUCCESS . getCode ( ) ) . message ( message) . data ( data) . build ( ) ; } public static < T > ResultWrapper < T > fail ( ) { return new Builder < T > ( ) . success ( false ) . code ( RespBeanEnum . ERROR . getCode ( ) ) . message ( RespBeanEnum . ERROR . getMessage ( ) ) . build ( ) ; } public static < T > ResultWrapper < T > fail ( String message) { return new Builder < T > ( ) . success ( false ) . code ( RespBeanEnum . ERROR . getCode ( ) ) . message ( message) . build ( ) ; } public static < T > ResultWrapper < T > fail ( int code, String message) { return new Builder < T > ( ) . success ( false ) . code ( code) . message ( message) . build ( ) ; } public static < T > ResultWrapper < T > fail ( int code, String message, T data) { return new Builder < T > ( ) . success ( false ) . code ( code) . message ( message) . data ( data) . build ( ) ; } public static < T > ResultWrapper < T > fail ( RespBeanEnum respBeanEnum) { return new Builder < T > ( ) . success ( false ) . code ( respBeanEnum. getCode ( ) ) . message ( respBeanEnum. getMessage ( ) ) . build ( ) ; }
}
2.common-web-starter
1.目录结构
2.IgnoredResultWrapper.java 自定义注解,忽略对返回结果的自动包装
package com. sunxiansheng. web. annotation ; import java. lang. annotation. ElementType ;
import java. lang. annotation. Retention ;
import java. lang. annotation. RetentionPolicy ;
import java. lang. annotation. Target ;
@Target ( { ElementType . METHOD } )
@Retention ( RetentionPolicy . RUNTIME )
public @interface IgnoredResultWrapper { }
3.ReturnValueHandlersDecorator.java 对适配器进行扩展的装饰器
package com. sunxiansheng. web. config ; import com. sunxiansheng. tool. response. ResultWrapper ;
import com. sunxiansheng. web. annotation. IgnoredResultWrapper ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. beans. factory. InitializingBean ;
import org. springframework. core. MethodParameter ;
import org. springframework. core. annotation. AnnotatedElementUtils ;
import org. springframework. web. bind. annotation. ResponseBody ;
import org. springframework. web. context. request. NativeWebRequest ;
import org. springframework. web. method. support. HandlerMethodReturnValueHandler ;
import org. springframework. web. method. support. ModelAndViewContainer ;
import org. springframework. web. servlet. mvc. method. annotation. RequestMappingHandlerAdapter ;
import org. springframework. web. servlet. mvc. method. annotation. RequestResponseBodyMethodProcessor ; import javax. annotation. Resource ;
import java. util. ArrayList ;
import java. util. List ;
import java. util. Objects ;
@Slf4j
public class ReturnValueHandlersDecorator implements InitializingBean { @Resource private RequestMappingHandlerAdapter requestMappingHandlerAdapter; @Override public void afterPropertiesSet ( ) { List < HandlerMethodReturnValueHandler > returnValueHandlers = requestMappingHandlerAdapter. getReturnValueHandlers ( ) ; assert returnValueHandlers != null ; List < HandlerMethodReturnValueHandler > handlers = new ArrayList < > ( returnValueHandlers) ; this . decorateHandlers ( handlers) ; requestMappingHandlerAdapter. setReturnValueHandlers ( handlers) ; } private void decorateHandlers ( List < HandlerMethodReturnValueHandler > returnValueHandlers) { for ( HandlerMethodReturnValueHandler returnValueHandler : returnValueHandlers) { if ( returnValueHandler instanceof RequestResponseBodyMethodProcessor ) { ControllerReturnValueHandler controllerReturnValueHandler = new ControllerReturnValueHandler ( returnValueHandler) ; int index = returnValueHandlers. indexOf ( returnValueHandler) ; returnValueHandlers. set ( index, controllerReturnValueHandler) ; } } } private static class ControllerReturnValueHandler implements HandlerMethodReturnValueHandler { private final HandlerMethodReturnValueHandler handler; public ControllerReturnValueHandler ( HandlerMethodReturnValueHandler handler) { this . handler = handler; } @Override public boolean supportsReturnType ( MethodParameter returnType) { return AnnotatedElementUtils . hasAnnotation ( returnType. getContainingClass ( ) , ResponseBody . class ) || returnType. hasMethodAnnotation ( ResponseBody . class ) ; } @Override public void handleReturnValue ( Object o, MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest) throws Exception { IgnoredResultWrapper methodAnnotation = methodParameter. getMethodAnnotation ( IgnoredResultWrapper . class ) ; if ( Objects . nonNull ( methodAnnotation) ) { handler. handleReturnValue ( o, methodParameter, modelAndViewContainer, nativeWebRequest) ; return ; } if ( o instanceof ResultWrapper ) { handler. handleReturnValue ( o, methodParameter, modelAndViewContainer, nativeWebRequest) ; return ; } log. info ( "Controller返回值已被自动包装,如果上传文件,请加@IgnoredResultWrapper注解取消自动包装!" ) ; ResultWrapper < Object > ok = ResultWrapper . ok ( o) ; handler. handleReturnValue ( ok, methodParameter, modelAndViewContainer, nativeWebRequest) ; } }
}
4.WebAutoConfiguration.java 将装饰器注入容器
@Bean @ConditionalOnMissingBean public ReturnValueHandlersDecorator returnValueHandlersDecorator ( ) { return new ReturnValueHandlersDecorator ( ) ; }
3.common-web-starter-demo
1.WebController.java 测试三种使用方式
package com. sunxiansheng. web. controller ; import com. sunxiansheng. tool. response. ResultWrapper ;
import com. sunxiansheng. web. annotation. IgnoredResultWrapper ;
import org. springframework. web. bind. annotation. RequestMapping ;
import org. springframework. web. bind. annotation. RestController ;
@RestController
public class WebController { @RequestMapping ( "/method1" ) public String method1 ( ) { return "method1" ; } @IgnoredResultWrapper @RequestMapping ( "/method2" ) public String method2 ( ) { return "method2" ; } @RequestMapping ( "/method3" ) public ResultWrapper < String > method3 ( ) { return ResultWrapper . fail ( "method3" ) ; }
}
2.测试
1.第一种:直接使用自动包装成功结果
2.第二种:使用 @IgnoredResultWrapper注解忽略掉自动包装
3.第三种:直接使用ResultWrapper来自己封装结果