美文网首页
Jackson全面解析--SpringBoot集成Jackson

Jackson全面解析--SpringBoot集成Jackson

作者: 牧羊人刘俏 | 来源:发表于2020-12-18 16:16 被阅读0次

    上一章讲解了sb中如何的对Jackson进行细粒度的配置,那么sb是如何在框架中嵌入Jackson呢,针对@ResponseBody注解的type或是method,sb会使用RequestResponseBodyMethodProcessor类来进行处理。其中的handleReturnValue方法,会将方法返回的对象进行Converter成我们需要的类型,不如json或是xml的类型。

    @Override
                                                              //返回的值
        public void handleReturnValue(@Nullable Object returnValue , 
                                                            //返回的类型
                                                            MethodParameter returnType,
                                                            //spring的modeView容器
                                               ModelAndViewContainer 
     //当前请求的request
     mavContainer, NativeWebRequest webRequest)
                throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
    
            mavContainer.setRequestHandled(true);
            ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
            ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
    
            // Try even with null return value. ResponseBodyAdvice could get involved.
            writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
        }
    
    

    核心的方法就是最后writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);

    那这些HttpMessageConverter是如何的注册到sb中的呢,肯定也是configure的配置了,在sb中提供了多处的configure来注册HttpMessageConverter。一个是
    HttpMessageConvertersAutoConfiguration,在改配置文件中注册了一个
    StringHttpMessageConverter的bean,由于import

    @Import({ JacksonHttpMessageConvertersConfiguration.class,
            GsonHttpMessageConvertersConfiguration.class,
            JsonbHttpMessageConvertersConfiguration.class })
    

    由于我的classpath是有jackson的,所以跟到JacksonHttpMessageConvertersConfiguration,其中注册了一个MappingJackson2HttpMessageConverter的bean,

    而在生成HttpMessageConverters bean的时候会调用WebMvcConfigurationSupport类的addDefaultHttpMessageConverters方法,在这个里面会继续的注册一些默认使用到的消息转换器。
    如下

    protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
            StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
            stringHttpMessageConverter.setWriteAcceptCharset(false);  // see SPR-7316
    
            messageConverters.add(new ByteArrayHttpMessageConverter());
            messageConverters.add(stringHttpMessageConverter);
            messageConverters.add(new ResourceHttpMessageConverter());
            messageConverters.add(new ResourceRegionHttpMessageConverter());
            try {
                messageConverters.add(new SourceHttpMessageConverter<>());
            }
            catch (Throwable ex) {
                // Ignore when no TransformerFactory implementation is available...
            }
            messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    
            if (romePresent) {
                messageConverters.add(new AtomFeedHttpMessageConverter());
                messageConverters.add(new RssChannelHttpMessageConverter());
            }
    
            if (jackson2XmlPresent) {
                Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
                if (this.applicationContext != null) {
                    builder.applicationContext(this.applicationContext);
                }
                messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));
            }
            else if (jaxb2Present) {
                messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
            }
    
            if (jackson2Present) {
                Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
                if (this.applicationContext != null) {
                    builder.applicationContext(this.applicationContext);
                }
                messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
            }
            else if (gsonPresent) {
                messageConverters.add(new GsonHttpMessageConverter());
            }
            else if (jsonbPresent) {
                messageConverters.add(new JsonbHttpMessageConverter());
            }
    
            if (jackson2SmilePresent) {
                Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.smile();
                if (this.applicationContext != null) {
                    builder.applicationContext(this.applicationContext);
                }
                messageConverters.add(new MappingJackson2SmileHttpMessageConverter(builder.build()));
            }
            if (jackson2CborPresent) {
                Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.cbor();
                if (this.applicationContext != null) {
                    builder.applicationContext(this.applicationContext);
                }
                messageConverters.add(new MappingJackson2CborHttpMessageConverter(builder.build()));
            }
        }
    

    通过这样的方式,sb在启动成功之后,在容器里面就有了这些默认的消息转化器,当然我们可以自定义消息转换器,然后注册进去,也可以实现我们的自定义逻辑

    相关文章

      网友评论

          本文标题:Jackson全面解析--SpringBoot集成Jackson

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