Spring @ResponseBody Jackson JsonSerializer с JodaTime

У меня ниже Serializer для обработки JodaTime:

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);
    }

}

Затем на каждом объекте модели я делаю следующее:

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

С приведенными выше настройками, @ResponseBody и Jackson Mapper работают. Однако мне не нравится идея, где я пишу @JsonSerialize. Мне нужно решение без @JsonSerialize на объектах модели. Возможно ли записать эту конфигурацию где-нибудь в spring xml в качестве одной конфигурации?

Цените свою помощь.

Ответ 1

Хотя вы можете поместить аннотацию для каждого поля даты, лучше сделать глобальную конфигурацию для вашего объекта mapper. Если вы используете jackson, вы можете настроить spring следующим образом:

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

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

Для 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)"));
    }
}

Конечно, SimpleDateFormat может использовать любой формат, который вам нужен.

Ответ 2

@Moesio в значительной степени получил его. Здесь моя конфигурация:

<!-- 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" />

Бит, который меня достал, заключается в том, что <mvc:annotation-driven/> делает свой собственный AnnotationMethodHandler и игнорирует тот, который вы делаете вручную. Я получил идею BeanPostProcessing от http://scottfrederick.blogspot.com/2011/03/customizing-spring-3-mvcannotation.html, чтобы настроить ту, которая используется, и voilà! Работает как шарм.

Ответ 3

То же самое с использованием JavaConfig 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;
    }
}

Ответ 4

Если вы просто используете JARs Jackson в своем пути к классам и возвращаете @ResponseBody, Spring автоматически преобразует объект Model в JSON. Вам не нужно ничего комментировать в Модели, чтобы заставить это работать.