jacksonJSON自定义序列化的某些领域
有没有办法使用jacksonJSON处理器做自定义字段级序列化? 例如,我想要上课
public class Person { public String name; public int age; public int favoriteNumber; }
序列化到以下JSON:
{ "name": "Joe", "age": 25, "favoriteNumber": "123" }
请注意,age = 25被编码为一个数字,而favoriteNumber = 123被编码为一个string 。 jackson(Jackson)封送给了一个数字。 在这种情况下,我希望favoriteNumber被编码为一个string。
您可以按如下方式实现自定义序列化器:
public class Person { public String name; public int age; @JsonSerialize(using = IntToStringSerializer.class, as=String.class) public int favoriteNumber: } public class IntToStringSerializer extends JsonSerializer<Integer> { @Override public void serialize(Integer tmpInt, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { jsonGenerator.writeObject(tmpInt.toString()); } }
Java应该为int
处理从int
到Integer
的自动装箱。
Jackson-databind(至less2.1.3)提供了特殊的ToStringSerializer
( com.fasterxml.jackson.databind.ser.std.ToStringSerializer
)
例:
public class Person { public String name; public int age; @JsonSerialize(using = ToStringSerializer.class) public int favoriteNumber: }
为favoriteNumber
字段添加一个@JsonProperty
注释的getter,它返回一个String
:
public class Person { public String name; public int age; private int favoriteNumber; public Person(String name, int age, int favoriteNumber) { this.name = name; this.age = age; this.favoriteNumber = favoriteNumber; } @JsonProperty public String getFavoriteNumber() { return String.valueOf(favoriteNumber); } public static void main(String... args) throws Exception { Person p = new Person("Joe", 25, 123); ObjectMapper mapper = new ObjectMapper(); System.out.println(mapper.writeValueAsString(p)); // {"name":"Joe","age":25,"favoriteNumber":"123"} } }
在@JsonView的帮助下,我们可以决定模型类的字段是否满足最低标准的序列化(我们必须定义标准),就像我们可以拥有一个具有10个属性的核心类,但是只有5个属性需要序列化只要
通过简单地创build以下类来定义我们的视图:
public class Views { static class Android{}; static class IOS{}; static class Web{}; }
带有视图的注释模型类:
public class Demo { public Demo() { } @JsonView(Views.IOS.class) private String iosField; @JsonView(Views.Android.class) private String androidField; @JsonView(Views.Web.class) private String webField; // getters/setters ... .. }
现在我们必须通过简单地从Spring扩展HttpMessageConverter类来编写自定义json转换器,如下所示:
public class CustomJacksonConverter implements HttpMessageConverter<Object> { public CustomJacksonConverter() { super(); //this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.ClientView.class)); this.delegate.getObjectMapper().configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true); this.delegate.getObjectMapper().setSerializationInclusion(Include.NON_NULL); } // a real message converter that will respond to methods and do the actual work private MappingJackson2HttpMessageConverter delegate = new MappingJackson2HttpMessageConverter(); @Override public boolean canRead(Class<?> clazz, MediaType mediaType) { return delegate.canRead(clazz, mediaType); } @Override public boolean canWrite(Class<?> clazz, MediaType mediaType) { return delegate.canWrite(clazz, mediaType); } @Override public List<MediaType> getSupportedMediaTypes() { return delegate.getSupportedMediaTypes(); } @Override public Object read(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { return delegate.read(clazz, inputMessage); } @Override public void write(Object obj, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { synchronized(this) { String userAgent = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("userAgent"); if ( userAgent != null ) { switch (userAgent) { case "IOS" : this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.IOS.class)); break; case "Android" : this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.Android.class)); break; case "Web" : this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( Views.Web.class)); break; default: this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( null )); break; } } else { // reset to default view this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( null )); } delegate.write(obj, contentType, outputMessage); } } }
现在需要告诉spring使用这个自定义json转换,只需将其放在dispatcher-servlet.xml中即可
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean id="jsonConverter" class="com.mactores.org.CustomJacksonConverter" > </bean> </mvc:message-converters> </mvc:annotation-driven>
这就是你将能够决定哪些字段序列化。
jackson-annotations提供了@JsonFormat
,它可以处理大量的定制,而无需编写自定义序列化程序。
例如,为数字types的字段请求STRING
形状将以stringforms输出数字值
public class Person { public String name; public int age; @JsonFormat(shape = JsonFormat.Shape.STRING) public int favoriteNumber; }
将导致期望的输出
{"name":"Joe","age":25,"favoriteNumber":"123"}