SpringBoot统一响应处理
目前很多项目都是前后端分离,在这样的大趋势下,后端向前端的响应结果规范格外地重要。
自定义响应结果
响应实体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| @Data @NoArgsConstructor @AllArgsConstructor public class ResponseEntityDemo<T> {
private int code;
private String message;
private T data;
public static <Type> ResponseEntityDemo<Type> successWithoutData() { return new ResponseEntityDemo<Type>(ResultCode.SUCCESS, null); }
public static <Type> ResponseEntityDemo<Type> successWithData(Type data) { return new ResponseEntityDemo<Type>(ResultCode.SUCCESS, data); }
public static <Type> ResponseEntityDemo<Type> failed(String message) { return new ResponseEntityDemo<Type>(ResultCode.FAILED.getCode(), message, null); }
public static <Type> ResponseEntityDemo<Type> failed(ResultCode resultCode) { return new ResponseEntityDemo<Type>(resultCode, null); }
public static <Type> ResponseEntityDemo<Type> failed() { return new ResponseEntityDemo<Type>(ResultCode.FAILED, null); } private ResponseEntityDemo(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.message = resultCode.getMsg(); this.data = data; }
}
|
响应状态码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Getter @AllArgsConstructor public enum ResultCode {
SUCCESS(200, "操作成功"),
FAILED(1001, "响应失败"),
VALIDATE_FAILED(1002, "参数校验失败"),
ERROR(5000, "未知错误");
private int code; private String msg;
}
|
响应数据的统一处理
先创建一个类加上注解使其成为全局处理类并使用同异常处理的全局处理所使用的@RestControllerAdvice注解。然后继承ResponseBodyAdvice
接口重写其中的方法,即可对我们的controller
进行增强操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @RestControllerAdvice(basePackages = {"com.wht.houtaidemo.controller"}) public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {
@Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> aClass) { return !returnType.getParameterType().equals(ResponseEntityDemo.class); }
@Override public Object beforeBodyWrite(Object result, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { return ResponseEntityDemo.successWithData(result); } }
|
Tip:ResponseBodyAdvice中supports
方法要返回为true
才会执行beforeBodyWrite
方法
上述写法会有一个小问题:
完整版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @RestControllerAdvice(basePackages = {"com.wht.houtaidemo.controller"}) public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {
@Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> aClass) { return !(returnType.getParameterType().equals(ResponseEntityDemo.class)||returnType.getParameterType().equals(ResponseEntity.class)); }
@Override public Object beforeBodyWrite(Object result, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { if(result == null){ return ResponseEntityDemo.failed(); }
if (returnType.getGenericParameterType().equals(String.class)) { ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.writeValueAsString(ResponseEntityDemo.successWithData(result)); } catch (JsonProcessingException e) { throw new APIException("返回String类型错误"); } } if(returnType.getGenericParameterType().equals(Boolean.class) && (Boolean)result == false){ return ResponseEntityDemo.failed(); }
return ResponseEntityDemo.successWithData(result); } }
|
测试
直接返回数据不进行响应包装
1 2 3 4 5 6 7
| @GetMapping("/getDemo") public TestDemo getTestDemo(){ TestDemo demo = new TestDemo(); demo.setId(1L); demo.setUsername("test"); return demo; }
|
结果:
参考