文章目录
- 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 {@Resourceprivate RequestMappingHandlerAdapter requestMappingHandlerAdapter;@Overridepublic 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;}@Overridepublic boolean supportsReturnType(MethodParameter returnType) {return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);}@Overridepublic 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@ConditionalOnMissingBeanpublic 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来自己封装结果