虽然本文命题是HttpMessageConverter,但是常用的场景是修改字段值,如果不是,那你自定义Converter是为了什么???
HttpMessageConverter是也是数据绑定接口,它负责实现HandlerMethodArgumentResolver的内部实现,注意HandlerMethodArgumentResolver对于不同的媒体类型(MIME),有不同的实现,其中Converter主要针对常用的媒体类型为application/json的类型(当然这是自定义的,只不过spring mvc默认是这么做的),而如果是表单类型,则处理字段直接使用PropertyEditor接口即可
本文简单介绍一下HttpMessageConverter的常用实现类MappingJackson2HttpMessageConverter如何处理字段映射,假设有如下实体类
public class TestUser {
private String userName;
private String description;
// 为了篇幅,省略get / set
@Override
public String toString() {
return "TestUser{" +
"userName='" + userName + '\'' +
", description='" + description + '\'' +
'}';
}
}
下面的代码会打印出TestUser{userName='文天', description='想睡武汉的妹子'}
,这个例子很简单,因为这就是使用jackson将字符串转换成java类再打印出来
public static void main(String[] args) throws Exception {
String str = "{\"userName\": \"文天\",\"description\": \"想睡武汉的妹子\"}";
ObjectMapper objectMapper = new ObjectMapper();
TestUser user = objectMapper.readValue(str, TestUser.class);
System.out.println(user);
}
下面有这样一个需求,在不改变str的情况下,将输出改成TestUser{userName='文天', description='想睡武汉汉阳的妹子'}
,注意,多了汉阳两个字,这该如何做呢,比较简单(但是跟源码确实花费了我很久才知道),就是使用JsonDeserializer
接口,首先定义一个字段接口,用来反序列化指定字段
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
public class DesDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// 你可以在这里做任意的事情,不过本类专门用于放在description字段上,
// 所以示例直接返回写死的字符串
System.out.println("deserialize:" + p.getCurrentName());
System.out.println("deserialize:" + p.getValueAsString());
return "想睡武汉汉阳的妹子";
}
}
然后将实体类改成如下(多了一个注解),之后再次运行main方法即可输出TestUser{userName='文天', description='想睡武汉汉阳的妹子'}
public class TestUser {
private String userName;
@JsonDeserialize(using = DesDeserializer.class)
private String description;
@Override
public String toString() {
return "TestUser{" +
"userName='" + userName + '\'' +
", description='" + description + '\'' +
'}';
}
}
笔记:本文主要核心关注点就是对字段维度的解析,与本接口有相同类似作用的还有PropertyEditor接口,请注意二者在媒体类型上的区别