Reputation: 16271
For a Spring Web Application working with Jackson for XML
and JSON
through:
These classes are used for Rest purposes and each one are configured through a @Bean
method and both use the following:
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(){
Jackson2Ob jectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.simpleDateFormat("yyyy-MM-dd");
return builder;
}
For Date
serialization is mandatory use:
@JsonProperty("fecha")
@JsonSerialize(using=JsonDateSerializer.class)
@XmlJavaTypeAdapter(XmlDateAdapter.class)
@JacksonXmlProperty(localName="fecha")
public Date getFecha() {
return fecha;
}
I want to know if is possible avoid these @JsonSerialize
and @XmlJavaTypeAdapter
annotations and trust through a central @Bean
method that offers a configuration that should be used for both these MappingJackson2HttpMessageConverter
and MappingJackson2XmlHttpMessageConverter
converters; where the Date
'serialization' should be applied from that configuration. Consider the same about 'formatting' numbers such as BigDecimal
and currency too.
Currently with the code shown above I must use @JsonSerialize
and @XmlJavaTypeAdapter
mandatorily.
Note: for Jackson XML, jackson-dataformat-xml
is used instead of JAXB 2
due a limitation about of Generic Collections.
Upvotes: 1
Views: 916
Reputation: 3943
Unless I am totally misunderstanding the context here, you can configure jackson Object mapper to use JaxbAnnotationIntrospector as well. With that Jackson will respect the jaxb annotations while marshalling/unmarshalling.
Usually the configuration for that looks something like this:
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(){
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
AnnotationIntrospector annotationIntrospector = 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;
}
And your entity date field will look like:
@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;
}
If you want to get rid of @XmlJavaTypeAdapter
altogether and just want it to be serialized the way you want in json, you can create a custom json serializer and deserializer classes extending jackson's JsonSerializer and JsonDeserializer.
One such example of a custom serializer from Jackson custom date serializer (I modified this to not rely on a custom annotation and hence to not implement 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));
}
Similarly, you will need to create a custom Deserializer as well if you intend to deserialize Date json element to Date object. Then register them for Date class with Jackson2ObjectMapperBuilder.
builder.serializerByType(Date.class, new CustomDateSerializer());
builder.deserializerByType(Date.class, new CustomDateDeSerializer());
Upvotes: 2