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的参数;