SpringBoot自定義MessageConvert詳細(xì)講解
前言
對(duì)于頁面攜帶的請(qǐng)求頭中的AcceptSpringBoot有對(duì)應(yīng)的10種MessageConvert可以支持寫出對(duì)應(yīng)的媒體類型,比如application/xml、application/json……
我們還可以通過向容器放入一個(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 處理方法返回值。通過 MessageConverter 處理
2、所有 MessageConverter 合起來可以支持各種媒體類型數(shù)據(jù)的操作(讀、寫)
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都能寫出哪些類型,我們這里也要自定義 * @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ù)的寫出 String data = person.getUsername() + ";" + person.getAge() + ";" +person.getPet() + ";"; //寫出去 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)訪問路徑攜帶format參數(shù)指明協(xié)商協(xié)議
比如:http://localhost:8080/test/person?format=x-person
記得先開啟基于參數(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ì)覆蓋原來的默認(rèn)ContentNegotiationConfigurer
到此這篇關(guān)于SpringBoot自定義MessageConvert詳細(xì)講解的文章就介紹到這了,更多相關(guān)SpringBoot MessageConvert內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
修改及反編譯可運(yùn)行Jar包實(shí)現(xiàn)過程詳解
這篇文章主要介紹了如何修改及反編譯可運(yùn)行Jar包,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09詳解SpringBoot中添加@ResponseBody注解會(huì)發(fā)生什么
這篇文章主要介紹了詳解SpringBoot中添加@ResponseBody注解會(huì)發(fā)生什么,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Skywalking改成適配阿里云等帶Http?Basic的Elasticsearch服務(wù)
這篇文章主要介紹了改造Skywalking支持阿里云等帶Http?Basic的Elasticsearch服務(wù)2022-02-02Java同步鎖Synchronized底層源碼和原理剖析(推薦)
這篇文章主要介紹了Java同步鎖Synchronized底層源碼和原理剖析,釋放后,進(jìn)入減減操作、直到為0然后喚醒隊(duì)列,讓他們?nèi)帄Z鎖,循環(huán)前面步驟,對(duì)Java同步鎖Synchronized相關(guān)知識(shí)感興趣的朋友一起看看吧2022-05-05SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值
這篇文章主要介紹了SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值,Spring是一個(gè)開源的框架,主要是用來簡化開發(fā)流程,通過IOC,依賴注入(DI)和面向接口實(shí)現(xiàn)松耦合,需要的朋友可以參考下2023-05-05字節(jié)二面SpringBoot可以同時(shí)處理多少請(qǐng)求
這篇文章主要為大家介紹了字節(jié)二面之SpringBoot可以同時(shí)處理多少請(qǐng)求面試分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07