有些時候呢,我們需要統一格式進行返回,之前可能會定義某個實體類在每個方法的響應都是用這個實體類然后包含響應值,其實spring呢,可以有挺多種無侵入的統一包裝方法。
第一種:
@RestControllerAdvice public class ResponseHandler implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { //這里可以實現自己的邏輯 判斷是否包裝 return true; } @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { if (o instanceof String) { //接口方法返回值為string的需要處理一下 因為響應的type為text 如果設置了響應為Json可以忽略 } return o; } }
第二種:
@Configuration public class RestReturnValueHandlerConfigurer implements InitializingBean {
@Autowired private RequestMappingHandlerAdapter handlerAdapter; @Override public void afterPropertiesSet() { List<HandlerMethodReturnValueHandler> list = handlerAdapter.getReturnValueHandlers(); List<HandlerMethodReturnValueHandler> newList = new ArrayList<>(); if (null != list) { for (HandlerMethodReturnValueHandler valueHandler: list) { if (valueHandler instanceof RequestResponseBodyMethodProcessor) { HandlerMethodReturnValueHandlerProxy proxy = new HandlerMethodReturnValueHandlerProxy(valueHandler); newList.add(proxy); } else { newList.add(valueHandler); } } } handlerAdapter.setReturnValueHandlers(newList); } } // 實現HandlerMethodReturnValueHandler接口 完成自己的結果處理器 public class HandlerMethodReturnValueHandlerProxy implements HandlerMethodReturnValueHandler { private HandlerMethodReturnValueHandler proxyObject; public HandlerMethodReturnValueHandlerProxy(HandlerMethodReturnValueHandler proxyObject) { this.proxyObject = proxyObject; } @Override public boolean supportsReturnType(MethodParameter returnType) { return proxyObject.supportsReturnType(returnType); } @Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { //這里實現自己的邏輯 proxyObject.handleReturnValue(resultValue, returnType, mavContainer, webRequest); } }
上述兩種方式都是可以實現自己的數據包裝,其實自己實現切面來進行包裝也是可以的。根據自己的業務類型,具體實現即可。不過都要注意響應頭格式,異常等處理,還有要記得處理第三方帶的接口的響應,比如spring的監控包,swagger-ui之類的接口。