用于MappingJackson2HttpMessageConverter和MappingJackson2XmlHttpMessageConverter

时间:2017-03-08 23:53:44

标签: json xml spring spring-mvc jackson

对于使用Jackson进行XMLJSON通过:

的Spring Web应用程序

这些类用于 Rest 目的,每个类都通过@Bean方法配置,并且都使用以下内容:

@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(){
    Jackson2Ob jectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.simpleDateFormat("yyyy-MM-dd");
    return builder;
}

对于Date序列化,必须使用:

@JsonProperty("fecha")
@JsonSerialize(using=JsonDateSerializer.class)
@XmlJavaTypeAdapter(XmlDateAdapter.class)
@JacksonXmlProperty(localName="fecha")
public Date getFecha() {
    return fecha;
}

我想知道是否可以通过提供应该使用的配置的中央@JsonSerialize方法来避免这些@XmlJavaTypeAdapter@Bean注释以及信任对于两者这些MappingJackson2HttpMessageConverterMappingJackson2XmlHttpMessageConverter转换器;应该从该配置应用Date'序列化'的位置。同样考虑“格式化”数字,例如BigDecimal和货币。

目前使用上面显示的代码,我必须强制使用@JsonSerialize@XmlJavaTypeAdapter

注意:对于Jackson XML,由于对通用集合的限制,使用jackson-dataformat-xml代替JAXB 2

1 个答案:

答案 0 :(得分:1)

除非我完全误解了上下文,否则您可以配置jackson Object mapper以使用JaxbAnnotationIntrospector。杰克逊将在编组/解组时尊重jaxb注释。

通常,配置看起来像这样:

@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(){
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    AnnotationIntrospector annotationIntrospector = new AnnotationIntrospector.Pair(
      new JaxbAnnotationIntrospector(),
      new JacksonAnnotationIntrospector()
    );
    builder.annotationIntrospector(annotationIntrospector);
    // This is to make jackson respect @XmlElementWrapper annotation and use wrapper name as the property name
    builder.defaultUseWrapper(true);
    return builder;
}

您的实体日期字段将如下所示:

@XmlJavaTypeAdapter(XmlDateAdapter.class)
@XmlElement(value = "fetcha") // This is not mandatory to add. If your class is annnotated with @XmlRootElement annotation, by default the field name will be picked up as the name of the element.
public Date getFecha() {
    return fecha;
}

如果你想完全摆脱@XmlJavaTypeAdapter并且希望它在json中按照你想要的方式被序列化,你可以创建一个自定义的json序列化器和反序列化器类来扩展jackson的JsonSerializer和JsonDeserializer。

来自console output的自定义序列化程序的一个这样的示例(我将其修改为不依赖于自定义注释,因此不实现ContextualSerializer)

 public static class CustomDateSerializer extends JsonSerializer<Date>
            {
        private final String format;

        private CustomDateSerializer(final String format) {this.format = format;}

        public CustomDateSerializer() {this.format = null;}

        @Override
        public void serialize(
                final Date value, final JsonGenerator jgen, final SerializerProvider provider)
                throws IOException {
            jgen.writeString(new SimpleDateFormat(format).format(value));
        }

同样,如果您打算将Date json元素反序列化为Date对象,则还需要创建自定义反序列化器。然后使用Jackson2ObjectMapperBuilder将它们注册到Date类。

builder.serializerByType(Date.class, new CustomDateSerializer());
builder.deserializerByType(Date.class, new CustomDateDeSerializer());