SpringBoot自定義MessageConvert詳細講解
前言
對於頁面攜帶的請求頭中的AcceptSpringBoot有對應的10種MessageConvert可以支持寫出對應的媒體類型,比如application/xml、application/json……
我們還可以通過向容器放入一個WebMvcConfigurer
實現定制化SpingMVC,自定義一個MessageConvert處理特殊的協議比如application/x-person
實現多協議數據兼容。json、xml、x-person
原理
0、@ResponseBody 響應數據出去 調用 RequestResponseBodyMethodProcessor 處理
1、Processor 處理方法返回值。通過 MessageConverter 處理
2、所有 MessageConverter 合起來可以支持各種媒體類型數據的操作(讀、寫)
3、內容協商找到最終的 messageConverter;
實現
/* 條件
*
* 1、瀏覽器發請求直接 返回xml [application/xml] jacksonXmlConverter
* 2、如果是ajax請求 返回json [application/json] jacksonJsonConverter
* 3、如果是app發請求,返回自定義協議數據 [application/x-person] xxxxConverter
*
* 步驟:
* 1、添加自定義的MessageConverter進系統底層
* 2、系統底層就會統計出所有MessageConverter能操作哪些類型
* 3、客戶端內容協商 [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 服務器需要統計所有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 { //自定義協會數據的寫出 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()); } } }
測試
拓展
如何實現訪問路徑攜帶format參數指明協商協議
比如:http://localhost:8080/test/person?format=x-person
記得先開啟基於參數的內容協商
spring:
mvc:
contentnegotiation:
favor-parameter: true
@Bean public WebMvcConfigurer webMvcConfigurer() { return new WebMvcConfigurer() { /* * 自定義內容協商策略 */ @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")); //指定支持解析那些參數的媒體類型 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()); } }; }
測試
註意:有可能我們添加的自定義的功能會覆蓋默認很多功能,導致一些默認的功能失效。比如上面的ContentNegotiationConfigurer 就會覆蓋原來的默認ContentNegotiationConfigurer
到此這篇關於SpringBoot自定義MessageConvert詳細講解的文章就介紹到這瞭,更多相關SpringBoot MessageConvert內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- fastjson全局日期序列化設置導致JSONField失效問題解決方案
- 一篇文章帶你深入瞭解Java對象與Java類
- 新手瞭解java 反射基礎知識
- SpringBoot2.0解決Long型數據轉換成json格式時丟失精度問題
- 淺談Java中Collections.sort對List排序的兩種方法