Jackson全面解析--SpringBoot集成Jackson
上一章讲解了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在启动成功之后,在容器里面就有了这些默认的消息转化器,当然我们可以自定义消息转换器,然后注册进去,也可以实现我们的自定义逻辑