15

I have below Serializer for JodaTime handling:

public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> {

    private static final String dateFormat = ("MM/dd/yyyy");

    @Override
    public void serialize(DateTime date, JsonGenerator gen, SerializerProvider provider)
            throws IOException, JsonProcessingException {

        String formattedDate = DateTimeFormat.forPattern(dateFormat).print(date);

        gen.writeString(formattedDate);
    }

}

Then, on each model objects, I do this:

@JsonSerialize(using=JodaDateTimeJsonSerializer.class )
public DateTime getEffectiveDate() {
    return effectiveDate;
}

With above settings, @ResponseBody and Jackson Mapper sure works. However, I don't like the idea where I keep writing @JsonSerialize. What I need is a solution without the @JsonSerialize on model objects. Is it possible to write this configuration somewhere in spring xml as a one configuration?

Appreciate your help.

Firdous Amir
  • 1,297
  • 5
  • 21
  • 39

5 Answers5

11

Although you can put an annotation for each date field, is better to do a global configuration for your object mapper. If you use jackson you can configure your spring as follow:

<bean id="jacksonObjectMapper" class="com.company.CustomObjectMapper" />

<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
    factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" >
</bean>

For CustomObjectMapper:

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        super();
        configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false);
        setDateFormat(new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'ZZZ (z)"));
    }
}

Of course, SimpleDateFormat can use any format you need.

Patrick
  • 2,672
  • 3
  • 31
  • 47
Moesio
  • 3,100
  • 1
  • 27
  • 36
1

@Moesio pretty much got it. Here's my config:

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven/>

<!-- Instantiation of the Default serializer in order to configure it -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterConfigurer" init-method="init">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                <property name="objectMapper" ref="jacksonObjectMapper" />
            </bean>
        </list>
    </property>
</bean>

<bean id="jacksonObjectMapper" class="My Custom ObjectMapper"/>

<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
    factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" />

The bit that got me is that <mvc:annotation-driven/> makes its own AnnotationMethodHandler and ignores the one you make manually. I got the BeanPostProcessing idea from http://scottfrederick.blogspot.com/2011/03/customizing-spring-3-mvcannotation.html to configure the one that gets used, and voilà! Works like a charm.

caseyboardman
  • 799
  • 2
  • 11
  • 26
0

Same using JavaConfig of Spring 3:

@Configuration
@ComponentScan()
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter
{

    @Override
    public void configureMessageConverters(final List<HttpMessageConverter<?>> converters)
    {
        converters.add(0, jsonConverter());
    }

    @Bean
    public MappingJacksonHttpMessageConverter jsonConverter()
    {
        final MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
        converter.setObjectMapper(new CustomObjectMapper());

        return converter;
    }
}
user2777500
  • 111
  • 5
0

If you are using Spring Boot, try this in application.yml :

spring:
    jackson:
       date-format: yyyy-MM-dd
       time-zone: Asia/Shanghai
       joda-date-time-format: yyyy-MM-dd
-3

If you simply have the Jackson JARs on your classpath, and return a @ResponseBody, Spring will automatically convert the Model object to JSON. You don't need to annotate anything in the Model to get this to work.

atrain
  • 9,139
  • 1
  • 36
  • 40
  • Well I tried. When Jackson converted the object into JSON, It converted JodaTime instance into a String with Millisecond in it. That's why a custom converter. I really want to avoid using @JsonSerialize in all my date variables. I need a way configure it in application level. – Firdous Amir May 24 '12 at 12:13
  • Look like I was incorrect in my assumption. There is actually a related Spring bug (https://jira.springsource.org/browse/SPR-6731), but even there, its to get the default annotations to work. So, it appears that you need to annotate in each model class. – atrain May 24 '12 at 12:53
  • I understand. Not sure if anybody has success configuring this in AOP style. Let's wait if somebody else has any comments. – Firdous Amir May 24 '12 at 18:53