Spring: @ControllerAdvice & @ResponseBodyAdvice
Config:
package io.jot.memento; import org.springframework.context.annotation.Configuration; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @Configuration public class Config{ @ControllerAdvice static class MyControllerAdvice implements ResponseBodyAdvice{ @Override public boolean supports(MethodParameter returnType, Class converterType){ if(returnType.getMethodAnnotation(ResponseBody.class) != null || AnnotationUtils.findAnnotation(returnType.getContainingClass(), ResponseBody.class) != null /*returnType.getContainingClass().isAnnotationPresent(ResponseBody.class)*/){ return true; } return false; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response){ if(body instanceof Result) return body; return Result.ok(body); } } // @Controller // @ResponseBody @RestController public static class MyController{ public User user(){ return new User("bbbbbbbbbb", 55); } } public static class User{ private String name; private int age; public User(String name, int age){ this.name = name; this.age = age; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public int getAge(){ return age; } public void setAge(int age){ this.age = age; } } }
Result:
package io.jot.memento; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @JsonInclude(JsonInclude.Include.NON_NULL) public class Result{ private int code; private String msg; private Object data; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } @JsonCreator private Result(@JsonProperty("code") int code, @JsonProperty("data") Object data) { this.code = code; this.data = data; } private Result(int code, String msg) { this.code = code; this.msg = msg; } public static Result ok() { return new Result(200, null); } public static Result ok(Object data) { return new Result(200, data); } public static Result error(String msg) { return new Result(500, "服务器内部错误:" + msg); } }
package io.jot.memento; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.method.ControllerAdviceBean; import org.springframework.web.method.annotation.ExpressionValueMethodArgumentResolver; import org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver; import org.springframework.web.method.annotation.RequestParamMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite; import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.servlet.mvc.method.annotation.*; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class Venal{ public static void main(String[] args) throws Exception{ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); ServletInvocableHandlerMethod handlerMethod = new ServletInvocableHandlerMethod(context.getBean(Config.MyController.class), Config.MyController.class.getMethod("user")); handlerMethod.setDataBinderFactory(new ServletRequestDataBinderFactory(Collections.emptyList(), null)); handlerMethod.setHandlerMethodArgumentResolvers(getArgumentResolvers(context)); handlerMethod.setHandlerMethodReturnValueHandlers(getReturnValueHandlers(context)); handlerMethod.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer()); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); handlerMethod.invokeAndHandle(new ServletWebRequest(request, response), new ModelAndViewContainer()); System.out.println("\033[37;7m>>>>>> " + new String(response.getContentAsByteArray(), StandardCharsets.UTF_8) + " <<<<<<\033[0m"); context.close(); } public static HandlerMethodArgumentResolverComposite getArgumentResolvers(AnnotationConfigApplicationContext context){ HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite(); composite.addResolvers( new RequestParamMethodArgumentResolver(context.getDefaultListableBeanFactory(), false), new PathVariableMethodArgumentResolver(), new RequestHeaderMethodArgumentResolver(context.getDefaultListableBeanFactory()), new ServletCookieValueMethodArgumentResolver(context.getDefaultListableBeanFactory()), new ExpressionValueMethodArgumentResolver(context.getDefaultListableBeanFactory()), new ServletRequestMethodArgumentResolver(), new ServletModelAttributeMethodProcessor(false), new RequestResponseBodyMethodProcessor(List.of(new MappingJackson2HttpMessageConverter())), new ServletModelAttributeMethodProcessor(true), new RequestParamMethodArgumentResolver(context.getDefaultListableBeanFactory(), true) ); return composite; } public static HandlerMethodReturnValueHandlerComposite getReturnValueHandlers(AnnotationConfigApplicationContext context){ // 添加 advice List<ControllerAdviceBean> annotatedBeans = ControllerAdviceBean.findAnnotatedBeans(context); List<Object> collect = annotatedBeans.stream().filter(b -> ResponseBodyAdvice.class.isAssignableFrom(b.getBeanType())) .collect(Collectors.toList()); HandlerMethodReturnValueHandlerComposite composite = new HandlerMethodReturnValueHandlerComposite(); composite.addHandler(new ModelAndViewMethodReturnValueHandler()); composite.addHandler(new ViewNameMethodReturnValueHandler()); composite.addHandler(new ServletModelAttributeMethodProcessor(false)); composite.addHandler(new HttpEntityMethodProcessor(List.of(new MappingJackson2HttpMessageConverter()))); composite.addHandler(new HttpHeadersReturnValueHandler()); composite.addHandler(new RequestResponseBodyMethodProcessor(List.of(new MappingJackson2HttpMessageConverter()), collect)); composite.addHandler(new ServletModelAttributeMethodProcessor(true)); return composite; } }
分类:
Spring
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2020-06-01 miscellanea