自定義Jackson的ObjectMapper如何實現(xiàn)@ResponseBody的自定義渲染
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean1" class="test.Bean1" />
<bean id="bean2" class="test.Bean2" />
</beans>通常,我們可以采用下面的Java Config方式代替上面的Xml,實現(xiàn) fine-grained(細粒度) 配置。
Java Config
package test;
@Configuration
public class WebConfig {
@Bean
public Bean1 bean1(){
//……
}
@Bean
public Bean2 bean2(){
//……
}
}XXXConfigurer
但是,有時候我們希望:
一組功能相關的Bean之間能夠建立更直接更明確的關系。
那么我們可以選擇實現(xiàn) XXXConfigurer 這類 回調接口,然后使用 @Configuration注解該實現(xiàn)類,并Override它們的抽象方法。
例如:
| 功能 | 回調接口 |
|---|---|
| 緩存 | org.springframework.cache.annotation.CachingConfigurer |
| 定時任務 | org.springframework.scheduling.annotation.SchedulingConfigurer |
| 異步(并發(fā))任務 | org.springframework.scheduling.annotation.AsyncConfigurer |
| Spring MVC高級配置 | org.springframework.web.servlet.config.annotation.WebMvcConfigurer |
注意:
XXXConfigurer 接口的實現(xiàn)類無疑需要復寫其全部抽象方法(Java8之前,Spring舊版本),但是如果不希望覆蓋默認或增加額外配置:
- 方法有返回值,則 return null。
- 方法無返回值,則不寫任何實現(xiàn)代碼。
- 當然你也可以直接繼承其抽象適配器
XXXConfigurerAdapter,根據(jù)配置需要復寫方法。 - 當然
Java8以后,接口方法有了默認實現(xiàn)default,在新版的Spring中,你可以直接實現(xiàn)XXXConfigurer接口,并根據(jù)配置復寫方法。
示例:WebMvcConfigurer
我們以 WebMvcConfigurer 為例:自定義Jackson的ObjectMapper,實現(xiàn)@ResponseBody的自定義渲染?
- 解決方法是配置Spring MVC的 HttpMessageConverter 消息轉換器
先來看xml方式
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<mvc:annotation-driven >
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
p:serializationInclusion="NON_NULL"/>WebMvcConfigurer的抽象適配器
我們還可以通過繼承 WebMvcConfigurer 的抽象適配器
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
來實現(xiàn)Spring MVC在Java Config 形式下的高級配置:
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper mapper = new ObjectMapper();
mapper.setDefaultPropertyInclusion(Include.NON_NULL);
converters.add(new MappingJackson2HttpMessageConverter(mapper));
}
}@EnableWebMvc
到這里,我們已經實現(xiàn)了Spring MVC在Java Config 形式下的高級配置,但是需要注意,這里我們使用了 @EnableWebMvc。
@EnableWebMvc源碼
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}第4行,導入了配置類
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
DelegatingWebMvcConfiguration源碼
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
}可以看到,DelegatingWebMvcConfiguration的作用就是注入WebMvcConfigurer的實現(xiàn)類, 而 DelegatingWebMvcConfiguration 又需要@EnableWebMvc來導入。
所以如果你沒有使用Spring Boot,而是傳統(tǒng)的
Spring項目,又想要使用WebMvcConfigurer來實現(xiàn)細粒度配置,你需要@EnableWebMvc。
官方文檔上給出了另一種解決方式:
If WebMvcConfigurer does not expose some advanced setting that needs to be configured,
consider removing the @EnableWebMvc annotation and extending directly from
WebMvcConfigurationSupport or DelegatingWebMvcConfiguration,
如果WebMvcConfigurer沒能解決你的需求,那么你可以考慮移除 @EnableWebMvc并且直接繼承WebMvcConfigurationSupport or DelegatingWebMvcConfiguration。
注意:
Spring boot已經通過Spring MVC的自動配置類WebMvcAutoConfiguration導入了DelegatingWebMvcConfiguration,所以不再需要@EnableWebMvc。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
相對的,如果你使用了@EnableWebMvc,那么Spring MVC的自動配置將被忽略。
@EnableXXX與<xxx:annotation-driven>的沖突
對于傳統(tǒng)Spring項目,Java Config的使用勢必導致Xml 與Java Config 同時存在于項目中。
這時候就需要我們去考慮Xml與annotation-based之間是否會產生沖突。
比如下面這些基本功能相同的標簽和注解:
這里強調基本功能,因為Java Config的配置更細粒度,自然容易獲得其他擴展導致某些功能不一致。
例如:@EnableWebMvc導入了DelegatingWebMvcConfiguration,從而實現(xiàn)了WebMvcConfigurer接口的注入。
<cache:annotation-driven /> <!--@EnableCaching--> <task:annotation-driven scheduler=""/> <!--@EnableScheduling--> <task:annotation-driven executor=""/> <!--@EnableAsync--> <mvc:annotation-driven /> <!--@EnableWebMvc--> <!-- …… 等等,諸如此類 -->
這里還是以<mvc:annotation-driven />與 @EnableWebMvc為例,如果二者同時存在:
- 傳統(tǒng)Spring項目以
web.xml加載dispatcher-servlet.xml,毫無疑問配置在xml中的<mvc:annotation-driven />將會優(yōu)先生效。 - 所以,此時
@EnableWebMvc不生效,WebMvcConfigurer的實現(xiàn)類將不會被注入,Java Config的配置方式不會生效。 - 所以,這種情況需要二選一。
至于,其他**XXXConfigurer** 在傳統(tǒng)Spring項目中的配置方式,與示例同理。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
基于Apache組件分析對象池原理的實現(xiàn)案例分析
本文從對象池的一個簡單案例切入,主要分析common-pool2組件關于:池、工廠、配置、對象管理幾個角色的源碼邏輯,并且參考其在Redis中的實踐,對Apache組件分析對象池原理相關知識感興趣的朋友一起看看吧2022-04-04
Java數(shù)據(jù)結構之KMP算法的實現(xiàn)
這篇文章主要為大家詳細介紹了Java數(shù)據(jù)結構中KMP算法的原理與實現(xiàn),文中的示例代碼講解詳細,對我們學習Java有一定的幫助,需要的可以參考一下2022-11-11
基于SpringBoot項目遇到的坑--Date入?yún)栴}
這篇文章主要介紹了SpringBoot項目遇到的坑--Date入?yún)栴},具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
prometheus數(shù)據(jù)遠程寫入elasticsearch方式
這篇文章主要介紹了prometheus數(shù)據(jù)遠程寫入elasticsearch方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-06-06
Spring Boot 2.x 實現(xiàn)文件上傳功能
這篇文章主要介紹了Spring Boot 2.x 實現(xiàn)文件上傳功能,本文分步驟通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
解決cmd執(zhí)行javac報錯:不是內部或外部命令,也不是可運行的程序
剛接觸JAVA的新手可能就不知道怎么解決'JAVAC'不是內部命令或外部命令,這篇文章主要給大家介紹了關于解決cmd執(zhí)行javac報錯:不是內部或外部命令,也不是可運行的程序的相關資料,需要的朋友可以參考下2023-11-11
Spring Security SecurityContextHolder組件示例說明
SpringSecurity的SecurityContextHolder組件是存儲當前安全上下文的地方,包括認證用戶信息,它支持全局訪問、線程局部存儲和上下文傳播,是SpringSecurity認證和授權的核心,文章通過示例展示了如何訪問已認證用戶的詳細信息、手動設置認證信息以及使用認證信息保護方法2024-11-11

