美文网首页
Springboot引用jackson-dataformat-x

Springboot引用jackson-dataformat-x

作者: 百恼神烦 | 来源:发表于2020-12-16 09:54 被阅读0次

    问题描述

    引用jackson-dataformat-xml后,原本返回json的接口全部返回了xml,除了前端调用时因有加特定的请求头而可以返回json外,尤其是后端服务间调用时全部返回了xml,导致json反序列化失败。

    解决过程

    让xml解析顺序重新排序

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            // 重新加入Jackson解析json的类,让其顺序排在xml解析的前面
            converters.add(new MappingJackson2HttpMessageConverter());
        }
    }
    
    

    注意这里千万不能再加个@EnableWebMvc,会导致之前注入的Converter全部失效,参照这里
    然而这并不一直能解决问题,实际中发现有些接口能调整回来,有些不能,原因大概是用谷歌浏览器访问时,它的Accept如果没有指定,默认xml会排在前面申请;还有服务间的通信,由于之前没有指定还是返回了xml。服务间通信是直接使用RestTemplate的,直接new,为了方便管理,改为注入一个写了Accept头的对象。
    实现一个ClientHttpRequestInterceptor,便于加入Header配置

    public class HeaderInterceptor implements ClientHttpRequestInterceptor {
        private final Map<String,String> headers = new HashMap<>();
    
        public void setHeader(String key,String value){
            headers.put(key,value);
        }
    
    
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            for(String k : headers.keySet()){
                request.getHeaders().set(k,headers.get(k));
            }
            return execution.execute(request, body);
        }
    }
    

    注入RestTemplate

        @Bean
        public RestTemplate restTemplate(){
            RestTemplate restTemplate = new RestTemplate();
            HeaderInterceptor interceptor = new HeaderInterceptor();
            interceptor.setHeader("Accept","application/json");
            restTemplate.setInterceptors(Arrays.asList(interceptor));
            return restTemplate;
        }
    

    顺便提一句,@ResqustMapping(produces="application/json") 也是可以的,然而太麻烦,反正前端在请求时会指定content-type,这个似乎会暗示返回结果,因此也能稳定返回json格式

    牢骚

    我这边发现配置Media解析顺序用处不大,尤其是用谷歌浏览器时,它的Accept拿到就是xml排前面的,因此下面的设置没什么用

        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.defaultContentType(xxx)
        }
    

    相关文章

      网友评论

          本文标题:Springboot引用jackson-dataformat-x

          本文链接:https://www.haomeiwen.com/subject/sguwgktx.html