对于spring boot 使用@RestController 注解,使得controller 方法的返回结果最后会是json格式,但是json格式并不固定,如何才嫩定制呢?
上次发表的方式有点啰嗦和麻烦,已将其删除,现在提供更加优雅的一种方式:
首先我们要先实现:
HandlerMethodReturnValueHandler 接口,
JSON定制读者自定义实现, 这里贴出一个简单的实现:
/**
*
* 定制JSON返回结果,简易的实现
* Created by caoawei on 2018/7/30.
*/
public class JsonHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class));
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
mavContainer.setRequestHandled(true);
HttpServletRequest request = getNativeRequest(webRequest);
HttpServletResponse response = getNativeResponse(webRequest);
writeWithMessageConverters(returnValue, returnType, request, response);
}
private static void writeWithMessageConverters(Object returnValue, MethodParameter returnType, HttpServletRequest request, HttpServletResponse response) {
JsonResult jr = JsonResultFactory.create(returnValue);
String rs = Utils.toJson(jr);
String encoding = request.getCharacterEncoding();
try {
response.setCharacterEncoding(encoding);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(rs);
response.getWriter().flush();
} catch (Exception e) {
throw new BizException(e);
}
}
private static HttpServletRequest getNativeRequest(NativeWebRequest webRequest){
return webRequest.getNativeRequest(HttpServletRequest.class);
}
private static HttpServletResponse getNativeResponse(NativeWebRequest webRequest){
return webRequest.getNativeResponse(HttpServletResponse.class);
}
}
下面就是如何让自定义的 HandlerMethodReturnValueHandler 生效并能够替代默认的json格式结果,
接下来就是通过实现 WebMvcRegistrations 接口,并实现
RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() 方法,
因此我们需要重写 RequestMappingHandlerAdapter ,但我们只需要继承此类,重写:
public void afterPropertiesSet() 方法即可,
实现如下:
@Configuration
public class WebConfig implements WebMvcConfigurer,WebMvcRegistrations {
/**
* JSON统一返回结果定制.默认情况下自定义的HandlerMethodReturnValueHandler
* 是放在末尾的,一般情况下执行不了
* @return
*/
@Override
public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
return new RequestMappingHandlerAdapter() {
@Override
public void afterPropertiesSet() {
// 由父类方法加载所有的 HandlerMethodReturnValueHandler
super.afterPropertiesSet();
// 不可修改的List
List
// returnValueHandlers副本
List
// 将自定义的Handler添加的首位
newreturnValueHandlers.set(0,new JsonHandlerMethodReturnValueHandler());
// 设置新值
super.setReturnValueHandlers(newreturnValueHandlers);
}
};
}
}
不过这里有个问题, 如果是分布式,且各个微服务都是使用这样的json定制的话,会导致使用
spring cloud时获取不到结果,所以说这样的话还是需要对spring cloud(假设您使用了feign) feign进行一些定制,不过本人尚未
对spring cloud feign进行深入的了解, 等到下次再分享于大家.
至此结束.