有些时候呢,我们需要统一格式进行返回,之前可能会定义某个实体类在每个方法的响应都是用这个实体类然后包含响应值,其实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之类的接口。