springboot自定義消息轉換器HttpMessageConverter

  在SpringMVC中,可使用@RequestBody和@ResponseBody兩個註解,分別完成請求報文到對象和對象到響應報文的轉換,底層這種靈活的消息轉換機制就是利用HttpMessageConverter來實現的,Spring內置了不少HttpMessageConverter,好比MappingJackson2HttpMessageConverter,StringHttpMessageConverter等,下面咱們來自定義本身的消息轉換器來知足本身特定的需求,有兩種方式:一、使用spring或者第三方提供的現成的HttpMessageConverter,二、本身重寫一個HttpMessageConverter。java

配置使用FastJson插件返回json數據

  在springboot項目裏當咱們在控制器類上加上@RestController註解或者其內的方法上加入@ResponseBody註解後,默認會使用jackson插件來返回json數據,下面咱們利用fastjson爲咱們提供的FastJsonHttpMessageConverter來返回json數據。web

  首先要引入fastjson的依賴:spring

     <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.31</version>
        </dependency>

  接下來經過實現WebMvcConfigurer接口來配置FastJsonHttpMessageConverter,springboot2.0版本之後推薦使用這種方式來進行web配置,這樣不會覆蓋掉springboot的一些默認配置。配置類以下:json

package com.example.demo; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; @Configuration public class MyWebmvcConfiguration implements WebMvcConfigurer{ @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fjc = new FastJsonHttpMessageConverter(); FastJsonConfig fj = new FastJsonConfig(); fj.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); fjc.setFastJsonConfig(fj); converters.add(fjc); } }

  fastJson配置實體調用setSerializerFeatures方法能夠配置多個過濾方式,經常使用的以下:springboot

  一、WriteNullListAsEmpty  :List字段若是爲null,輸出爲[],而非null
  二、WriteNullStringAsEmpty : 字符類型字段若是爲null,輸出爲"",而非null
  三、DisableCircularReferenceDetect :消除對同一對象循環引用的問題,默認爲false(若是不配置有可能會進入死循環)
  四、WriteNullBooleanAsFalse:Boolean字段若是爲null,輸出爲false,而非null
  五、WriteMapNullValue:是否輸出值爲null的字段,默認爲false。
  其它的相關類,咱們引入了lombok插件
package com.example.demo; import java.util.ArrayList; import java.util.List; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @RequestMapping(value="/get",method=RequestMethod.GET) public Object getList(){ List<UserEntity> list= new ArrayList<UserEntity>(); UserEntity u1 = new UserEntity(null, "shanghai"); list.add(u1); return list; }  }
package com.example.demo; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class UserEntity { private String name; private String address; }

  設置端口爲8888,啓動項目訪問http://localhost:8888/get,咱們代碼中沒有配置WriteMapNullValue,因此若是返回結果中有null值則不顯示,結果以下:mvc

  咱們註釋掉fastjson配置,從新啓動項目並訪問,從結果能夠看出咱們配置的消息轉換器起做用了。app

重寫HttpMessageConverter

  接下來咱們繼承AbstractHttpMessageConverter來實現一個本身的消息轉換器,示例以下:ide

package com.example.demo; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.AbstractHttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.util.StreamUtils; import java.io.IOException; import java.nio.charset.Charset; public class MyMessageConverter extends AbstractHttpMessageConverter<UserEntity> { public MyMessageConverter() { // 新建一個咱們自定義的媒體類型application/xxx-junlin
        super(new MediaType("application", "xxx-junlin", Charset.forName("UTF-8"))); } @Override protected boolean supports(Class<?> clazz) { // 代表只處理UserEntity類型的參數。
        return UserEntity.class.isAssignableFrom(clazz); } /** * 重寫readlntenal 方法,處理請求的數據。代碼代表咱們處理由「-」隔開的數據,並轉成 UserEntity類型的對象。 */ @Override protected UserEntity readInternal(Class<? extends UserEntity> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { String temp = StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8")); String[] tempArr = temp.split("-"); return new UserEntity(tempArr[0],tempArr[1]); } /** * 重寫writeInternal ,處理如何輸出數據到response。 */ @Override protected void writeInternal(UserEntity userEntity, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { String out = "hello: " + userEntity.getName() + "-" + userEntity.getAddress(); outputMessage.getBody().write(out.getBytes()); } }

  將自定義的消息轉換器加入到springmvc容器中,以便被使用。post

package com.example.demo; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; @Configuration public class MyWebmvcConfiguration implements WebMvcConfigurer{ @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fjc = new FastJsonHttpMessageConverter(); FastJsonConfig fj = new FastJsonConfig(); fj.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); fjc.setFastJsonConfig(fj); converters.add(fjc); converters.add(converter()); } @Bean public MyMessageConverter converter() { return new MyMessageConverter(); } }

  UserController中加入測試的代碼測試

package com.example.demo; import java.util.ArrayList; import java.util.List; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @RequestMapping(value="/get",method=RequestMethod.GET) public Object getList(){ List<UserEntity> list= new ArrayList<UserEntity>(); UserEntity u1 = new UserEntity(null, "shanghai"); list.add(u1); return list; } @RequestMapping(method = RequestMethod.POST, value = "/convert") public @ResponseBody UserEntity converter(@RequestBody UserEntity user) { return user; } }

  啓動項目,使用postman來測試,從響應來看咱們的消息轉換器已經起做用了,以下:

  
相關文章
相關標籤/搜索