spring boot 定制返回结果json格式

对于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 = super.getReturnValueHandlers();

                // returnValueHandlers副本
                List newreturnValueHandlers = new ArrayList<>(returnValueHandlers);

                // 将自定义的Handler添加的首位
                newreturnValueHandlers.set(0,new JsonHandlerMethodReturnValueHandler());

                // 设置新值
                super.setReturnValueHandlers(newreturnValueHandlers);

            }
        };
    }

   

}

 

不过这里有个问题, 如果是分布式,且各个微服务都是使用这样的json定制的话,会导致使用

spring cloud时获取不到结果,所以说这样的话还是需要对spring cloud(假设您使用了feign) feign进行一些定制,不过本人尚未

对spring cloud feign进行深入的了解,  等到下次再分享于大家.

至此结束.

你可能感兴趣的:(java基础知识)