自定義一個自己的訊息轉換器
阿新 • • 發佈:2018-12-08
1.自定義個訊息轉換器,支援自己定義的content-type型別.首先準備好測試的controller類;
@PostMapping("/")
public Object test(@RequestBody UserInfo userInfo) {
return userInfo;
}
實體類
public class UserInfo {
private String age;
private String name;
setter,getter...
}
注意,在接收引數那裡要使用@RequestBody,(@requestBody註解常用來處理content-type不是預設的application/x-www-form-urlcoded),支援自定義或者預設的json的資料格式;
2.自定義訊息轉換器;我們的目的是把請求的引數為user=26-高楊的引數傳入物件,並且content-type為application/gao;
public class MyConverter extends AbstractHttpMessageConverter<Object> { public MyConverter(){ //只有appplication/gao的請求會到此轉換器 super(new MediaType("application","gao", Charset.forName("utf-8"))); } @Override //判斷是否進行轉換操作 protected boolean supports(Class<?> aClass) { System.out.println(aClass.isAssignableFrom(UserInfo.class)); return aClass.isAssignableFrom(UserInfo.class); } @Override //將請求引數讀入物件 protected Object readInternal(Class<? extends Object> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException { InputStream body = httpInputMessage.getBody(); BufferedReader b = new BufferedReader(new InputStreamReader(body)); String s = b.readLine(); System.out.println(s); String s1 = s.split("=")[1]; UserInfo u = new UserInfo(); u.setName(s1.split("-")[0]); u.setAge(s1.split("-")[1]); return u; } @Override public boolean canWrite(Class<?> clazz, MediaType mediaType) { return super.canWrite(clazz, mediaType); } @Override protected boolean canRead(MediaType mediaType) { return super.canRead(mediaType); } @Override //如果需要返回引數,這裡返回json protected void writeInternal(Object s, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException { httpOutputMessage.getBody().write(new ObjectMapper().writeValueAsString(s).getBytes()); } }
當然如果我們不寫返回引數的方法,那麼預設也會走返回json的方式,因為使用了@RestController,會自動判斷以何種方式轉換;
3.將轉換器配置到spring,有幾種方式(下面引用網上的文章):
// 新增converter的第一種方式,程式碼很簡單,也是推薦的方式 // 這樣做springboot會把我們自定義的converter放在順序上的最高優先順序(List的頭部) // 即有多個converter都滿足Accpet/ContentType/MediaType的規則時,優先使用我們這個 @Bean public MyConverter() { return new MyConverter(); } // 新增converter的第二種方式 // 通常在只有一個自定義WebMvcConfigurerAdapter時,會把這個方法裡面新增的converter(s)依次放在最高優先順序(List的頭部) // 雖然第一種方式的程式碼先執行,但是bean的新增比這種方式晚,所以方式二的優先順序 大於 方式一 @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // add方法可以指定順序,有多個自定義的WebMvcConfigurerAdapter時,可以改變相互之間的順序 // 但是都在springmvc內建的converter前面 converters.add(new MyConverter()); } // 新增converter的第三種方式 // 同一個WebMvcConfigurerAdapter中的configureMessageConverters方法先於extendMessageConverters方法執行 // 可以理解為是三種方式中最後執行的一種,不過這裡可以通過add指定順序來調整優先順序,也可以使用remove/clear來刪除converter,功能強大 // 使用converters.add(xxx)會放在最低優先順序(List的尾部) // 使用converters.add(0,xxx)會放在最高優先順序(List的頭部) @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new MyConverter()); }
___________________________________________________________________________________________________
還有一種接收form/data或application/x-www-form-urlencoded的轉換方式:
@Component
public class New implements Converter<String, String> {
@Override
public String convert(String s) {
return s + "測試";
}
}
在泛型上新增需要接收和轉換的型別;或者用Bean的方式註冊也是可以的;這種方式處理簡單的轉換,一般用在接收轉換時間;不需要@RequestBody的引數;