项目
博客
归档
资源链接
关于我
项目
博客
归档
资源链接
关于我
08| 通过注解构建公共的全局响应体
2024-07-30
·
·
原创
·
·
本文共 362个字,预计阅读需要 2分钟。
构建公共响应体注解:`nla-common\src\main\java\cn\nla\common\annotation\ResponseResult.java` ```java /** * 该注解作业于类或者方法上,将返回值对象包装返回体结构 */ @Retention(RUNTIME) @Target({TYPE, METHOD}) @Documented public @interface ResponseResult { } ``` 添加拦截器,拦截是否存在公共的响应体注解,如果存在补充标识:`nla-shop\nla-common\src\main\java\cn\nla\common\interceptor\ResponseResultInterceptor.java` ```java /** * 请求拦截,封装响应对象 */ @Slf4j @Component public class ResponseResultInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (handler instanceof HandlerMethod) { final HandlerMethod handlerMethod = (HandlerMethod) handler; final Class> clazz = handlerMethod.getBeanType(); final Method method = handlerMethod.getMethod(); if (clazz.isAnnotationPresent(ResponseResult.class)) { // 设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口中进行解析 request.setAttribute("RESPONSE_RESULT_OBJ", clazz.getAnnotation(ResponseResult.class)); } else if (method.isAnnotationPresent(ResponseResult.class)) { // 设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口中进行解析 request.setAttribute("RESPONSE_RESULT_OBJ", method.getAnnotation(ResponseResult.class)); } } return true; } } ``` 注册拦截器:`nla-common\src\main\java\cn\nla\common\config\WebConfig.java` ```java /** * 注册拦截器 */ @Configuration public class WebConfig implements WebMvcConfigurer { @Resource private ResponseResultInterceptor responseResultInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(responseResultInterceptor); } } ``` 修改全局响应处理器: `nla-common\src\main\java\cn\nla\common\exception\CustomExceptionHandler.java` ```java @Slf4j @ControllerAdvice public class CustomExceptionHandler implements ResponseBodyAdvice
{ @Resource private ObjectMapper objectMapper; @Override public boolean supports(MethodParameter methodParameter, Class extends HttpMessageConverter>> aClass) { ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (sra == null) { return false; } HttpServletRequest request = sra.getRequest(); ResponseResult responseResultAnn = (ResponseResult) request.getAttribute("RESPONSE_RESULT_OBJ"); return responseResultAnn != null; } @Override public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class extends HttpMessageConverter>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { log.info("into ResponseResult handle ...."); if (body instanceof JsonData) { return body; } // 对于一般的类型都没有问题,当处理字符串类型时,会抛出 xxx.包装类 cannot be cast to java.lang.String 的类型转换的异常 if (body == null || body instanceof String) { try { return objectMapper.writeValueAsString(JsonData.buildSuccess(body)); } catch (JsonProcessingException e) { log.error("JsonProcessingException", e); } } return JsonData.buildSuccess(body); } @ExceptionHandler(value = Exception.class) @ResponseBody public JsonData handle(Exception e) { //是不是自定义异常 if (e instanceof BizException) { BizException bizException = (BizException) e; log.error("[业务异常]", e); return JsonData.buildCodeAndMsg(bizException.getCode(), bizException.getMsg()); } else { log.error("[系统异常]", e); return JsonData.buildError("全局异常,未知错误"); } } } ``` 在业务的Controller中使用: `nla-user-service\src\main\java\cn\nla\user\controller\AddressController.java` ```java @ResponseResult @RestController @RequestMapping("/addressDO") public class AddressController { @Resource private AddressService addressService; @GetMapping("query") //@ResponseResult public List
query() { return addressService.list(); } } ```