springboot添加WebMvcConfigurerAdapter拦截器导致返回json和xml数据为空的问题

最近在项目中遇到一个很棘手的问题,需求是这样的:项目是springboot项目,要求提供对外的一个接口,并根据一个入参output来控制返回的是json数据还是xml数据,我http请求接口返回出去的是一个ResponseEntity对象,需求需要增加一个拦截器继承WebMvcConfigurerAdapter去重写一些业务,在没加拦截器之前接口正常返回数据,但加入拦截器后,接口正常返回200,debug一下也没问题,但postman和浏览器打开接口就是没有数据,相应体为空,此时将ResponseEntity换成自定义的一个对象或字符串返回出去就很正常,这个问题一直没搞明白,想着应该是ResponseEntity的问题,导致响应体是空的。

以上是本次的一个问题,然后我又换了另一种解决方法,将返回的ResponseEntity对象改为Object对象,并通过@ResponseBody控制返回的json或xml。返回的两种数据格式如下:

1.  若返回json数据,则直接返回一个对象,@ResponseBody会解析成json数据返回,此时查看接口的响应头中Content-Type为application/json;charset=UTF-8,这是正常的

2.  若返回xml数据,则通过jdk自带的转换类实现将对象转为xml格式数据JAXBContext context = JAXBContext.newInstance(obj.getClass());,最后返回xml格式的字符串,此时查看接口返回的Content-Type为application/json;charset=UTF-8,这是不正常的,然后代码中修改相应头的Content-Type:application/xml;charset=UTF-8也不生效,数据类似:

springboot添加WebMvcConfigurerAdapter拦截器导致返回json和xml数据为空的问题_第1张图片springboot添加WebMvcConfigurerAdapter拦截器导致返回json和xml数据为空的问题_第2张图片

出现以上问题后,就想着用springboot同时返回json和xml的控制方法,引入依赖jackson-dataformat-xml,通过拦截器对指定参数名来控制返回的数据格式

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WebInterceptor()).addPathPatterns("/**");
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false)   //是否支持后缀的方式
                .favorParameter(true)        //是否支持请求参数的方式
                .ignoreAcceptHeader(true)    //是否忽略HttpHeader上的Accept指定 
                .parameterName("output")    //请求参数名
                .defaultContentType(MediaType.APPLICATION_JSON_UTF8); //默认返回格式
    }
}

当output参数不传入或传入“json”时,默认返回json格式,当传入"xml"时返回xml格式,但是这里会有个问题,就是当传入随意参数时可能就无法返回数据了。

通过这种方法就暂时解决了我的问题!!!

附上我另外的一个定制需求:项目中有多个接口,有点接口默认返回json,但有的接口默认返回xml,这个时候光通过上面拦截器的方式可能不足够满足要求了。简单的方法就是重写上面new WebInterceptor()方法,在重写的postHandle方法中通过对outpu参数或某个接口进行控制。

public class WebInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        String output = request.getParameter("output");
        String requestURI = request.getRequestURI();
        //若传入参数为json
        if (StringUtils.equalsIgnoreCase(output, "json")) {
            //设置ContentType为application/json;charset=UTF-8
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        } else if (StringUtils.equalsIgnoreCase(output, "xml")) {
            //若传入参数为xml
            //设置ContentType为application/atom+xml
            response.setContentType(MediaType.APPLICATION_ATOM_XML_VALUE);
        } else {
            if (StringUtils.containsIgnoreCase(requestURI, "a")) {
                //当不传入output参数时,若接口是a接口,默认返回json
                //则设置ContentType为application/json;charset=UTF-8
                response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            } else {
                //当不传入output参数时,若接口是b接口,默认返回xml
                //则设置ContentType为application/atom+xml
                response.setContentType(MediaType.APPLICATION_ATOM_XML_VALUE);
            }
        }

    }
}

返回json和xml格式的三种方法:https://www.cnblogs.com/SunArmy/p/9988950.html

Spring MVC ContentNegotiation内容协商机制(一个请求路径返回多种数据格式)源码解析:https://blog.csdn.net/qq_27529917/article/details/78447806

你可能感兴趣的:(springboot添加WebMvcConfigurerAdapter拦截器导致返回json和xml数据为空的问题)