SpringBoot自定義MessageConvert詳細(xì)講解
前言
對(duì)于頁(yè)面攜帶的請(qǐng)求頭中的AcceptSpringBoot有對(duì)應(yīng)的10種MessageConvert可以支持寫(xiě)出對(duì)應(yīng)的媒體類型,比如application/xml、application/json……
我們還可以通過(guò)向容器放入一個(gè)WebMvcConfigurer
實(shí)現(xiàn)定制化SpingMVC,自定義一個(gè)MessageConvert處理特殊的協(xié)議比如application/x-person
實(shí)現(xiàn)多協(xié)議數(shù)據(jù)兼容。json、xml、x-person
原理
0、@ResponseBody 響應(yīng)數(shù)據(jù)出去 調(diào)用 RequestResponseBodyMethodProcessor 處理
1、Processor 處理方法返回值。通過(guò) MessageConverter 處理
2、所有 MessageConverter 合起來(lái)可以支持各種媒體類型數(shù)據(jù)的操作(讀、寫(xiě))
3、內(nèi)容協(xié)商找到最終的 messageConverter;
實(shí)現(xiàn)
/* 條件
*
* 1、瀏覽器發(fā)請(qǐng)求直接 返回xml [application/xml] jacksonXmlConverter
* 2、如果是ajax請(qǐng)求 返回json [application/json] jacksonJsonConverter
* 3、如果是app發(fā)請(qǐng)求,返回自定義協(xié)議數(shù)據(jù) [application/x-person] xxxxConverter
*
* 步驟:
* 1、添加自定義的MessageConverter進(jìn)系統(tǒng)底層
* 2、系統(tǒng)底層就會(huì)統(tǒng)計(jì)出所有MessageConverter能操作哪些類型
* 3、客戶端內(nèi)容協(xié)商 [person--->person]
*/
person類
@Data
public class Person {
public String username;
public Integer age;
public Pet pet;
}pet類
@Data
public class Pet {
public String name;
public Integer age;
}PersonMessageConvert
/*
* 自定義的Convert
*/
public class PersonMessageConvert implements HttpMessageConverter<Person> {
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return clazz.isAssignableFrom(Person.class);
}
/*
* @Description 服務(wù)器需要統(tǒng)計(jì)所有MessageConvert都能寫(xiě)出哪些類型,我們這里也要自定義
* @Param
**/
@Override
public List<MediaType> getSupportedMediaTypes() {
return MediaType.parseMediaTypes("application/x-person");
}
@Override
public Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//自定義協(xié)會(huì)數(shù)據(jù)的寫(xiě)出
String data = person.getUsername() + ";" + person.getAge() + ";" +person.getPet() + ";";
//寫(xiě)出去
OutputStream body = outputMessage.getBody();
body.write(data.getBytes());
}
}方法
@ResponseBody
@GetMapping("/test/person")
public Person getPeroson() {
Person person = new Person();
person.setUsername("張三");
person.setAge(18);
person.setPet(new Pet());
return person;
}WebMvcConfigurer
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new PersonMessageConvert());
}
}
}測(cè)試


拓展
如何實(shí)現(xiàn)訪問(wèn)路徑攜帶format參數(shù)指明協(xié)商協(xié)議
比如:http://localhost:8080/test/person?format=x-person
記得先開(kāi)啟基于參數(shù)的內(nèi)容協(xié)商
spring:
mvc:
contentnegotiation:
favor-parameter: true
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
/*
* 自定義內(nèi)容協(xié)商策略
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
Map<String, MediaType> mediaTypeMap = new HashMap<>();
mediaTypeMap.put("json", MediaType.APPLICATION_JSON);
mediaTypeMap.put("xml", MediaType.APPLICATION_XML);
mediaTypeMap.put("x-person",MediaType.parseMediaType("application/x-person"));
//指定支持解析那些參數(shù)的媒體類型
ParameterContentNegotiationStrategy parametertrategy = new ParameterContentNegotiationStrategy(mediaTypeMap);
HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
configurer.strategies(Arrays.asList(parametertrategy, headerStrategy));
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new PersonMessageConvert());
}
};
}測(cè)試



注意:有可能我們添加的自定義的功能會(huì)覆蓋默認(rèn)很多功能,導(dǎo)致一些默認(rèn)的功能失效。比如上面的ContentNegotiationConfigurer 就會(huì)覆蓋原來(lái)的默認(rèn)ContentNegotiationConfigurer
到此這篇關(guān)于SpringBoot自定義MessageConvert詳細(xì)講解的文章就介紹到這了,更多相關(guān)SpringBoot MessageConvert內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springBoot 與neo4j的簡(jiǎn)單整合示例
這篇文章主要介紹了springBoot 與neo4j的簡(jiǎn)單整合示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Java對(duì)數(shù)組實(shí)現(xiàn)選擇排序算法的實(shí)例詳解
這篇文章主要介紹了Java對(duì)數(shù)組實(shí)現(xiàn)選擇排序算法的實(shí)例,選擇排序的比較次數(shù)為 O(N^2)而交換數(shù)為O(N),需要的朋友可以參考下2016-04-04
Springboot @Autowired和@Resource的區(qū)別解析
@Resource是JDK 提供的注解,只是Spring 在實(shí)現(xiàn)上提供了這個(gè)注解的功能支持,本文給大家介紹Springboot @Autowired和@Resource的區(qū)別,感興趣的朋友一起看看吧2025-04-04
SpringBoot中的@ConditionalOnMissingBean注解使用詳解
這篇文章主要介紹了SpringBoot中的@ConditionalOnMissingBean注解使用詳解,@ConditionalOnMissingBean作用在@Bean定義上,也就是說(shuō)在容器加載它作用的Bean時(shí),檢查容器中是否存在目標(biāo)類型,需要的朋友可以參考下2024-01-01
教你用Java在個(gè)人電腦上實(shí)現(xiàn)微信掃碼支付
今天給大家?guī)?lái)的是Java實(shí)戰(zhàn)的相關(guān)知識(shí),文章圍繞著Java在個(gè)人電腦上實(shí)現(xiàn)微信掃碼支付展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
Java通過(guò)百度地圖API獲取定位(普通IP定位)的方法教程
這篇文章主要介紹了Java通過(guò)百度地圖API獲取定位的方法教程,首先說(shuō)明了實(shí)現(xiàn)這個(gè)功能的需求和初衷,然后詳細(xì)描述了利用百度地圖API實(shí)現(xiàn)這個(gè)功能的步驟,包括在百度地圖開(kāi)放平臺(tái)的準(zhǔn)備工作、學(xué)習(xí)官網(wǎng)API文檔、修改API的AK配置、Java代碼獲取定位等,需要的朋友可以參考下2024-11-11

