2012-05-18 2 views
13

J'ai ci-dessous sérialiseur pour la manutention JodaTime:Spring @ResponseBody Jackson JsonSerializer avec 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); 
    } 

} 

Ensuite, sur chaque objet du modèle, je fais ceci:

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

Avec les paramètres ci-dessus, @ResponseBody et Jackson Mapper fonctionne bien. Cependant, je n'aime pas l'idée où je continue à écrire @JsonSerialize. Ce dont j'ai besoin, c'est d'une solution sans les @JsonSerialize sur les objets modèles. Est-il possible d'écrire cette configuration quelque part au printemps xml en tant que configuration unique?

Appréciez votre aide.

Répondre

10

Bien que vous puissiez mettre une annotation pour chaque champ de date, mieux vaut effectuer une configuration globale pour votre mappeur d'objet. Si vous utilisez jackson vous pouvez configurer votre ressort comme suit:

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

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

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

Bien sûr, SimpleDateFormat peut utiliser tout format dont vous avez besoin.

+0

'setDateFormat (nouveau SimpleDateFormat (" aaaa-MM-dd'T'HH: mm: ssz "));' a fait l'affaire pour moi, merci – Konsumierer

-3

Si vous avez simplement les JAR de Jackson sur votre chemin de classe et que vous renvoyez un @ResponseBody, Spring convertira automatiquement l'objet Modèle en JSON. Vous n'avez pas besoin d'annoter quoi que ce soit dans le modèle pour que cela fonctionne.

+0

Eh bien, j'essayé. Lorsque Jackson a converti l'objet en JSON, il a converti l'instance JodaTime en une chaîne avec Milliseconde dedans. C'est pourquoi un convertisseur personnalisé. Je veux vraiment éviter d'utiliser @JsonSerialize dans toutes mes variables de date. J'ai besoin d'un moyen de le configurer au niveau de l'application. –

+0

On dirait que j'étais incorrect dans mon hypothèse. Il y a en fait un bug lié à Spring (https://jira.springsource.org/browse/SPR-6731), mais même là, c'est pour que les annotations par défaut fonctionnent. Ainsi, il semble que vous ayez besoin d'annoter dans chaque classe de modèle. – atrain

+0

Je comprends. Je ne sais pas si quelqu'un a réussi à configurer cela dans le style AOP. Attendons si quelqu'un d'autre a des commentaires. –

1

@Moesio l'a bien compris. Voici ma 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" /> 

Le bit qui m'a est que <mvc:annotation-driven/> fait son propre AnnotationMethodHandler et ne tient pas celui que vous faites manuellement. J'ai eu l'idée BeanPostProcessing de http://scottfrederick.blogspot.com/2011/03/customizing-spring-3-mvcannotation.html pour configurer celle qui est utilisée, et voilà! Fonctionne comme un charme.

0

Même en utilisant JavaConfig du printemps 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; 
    } 
} 
Questions connexes