J'ai récemment mis à niveau ma version de Spring à la version 3.2.0 à partir de la version 3.1.2. Je trouve que les propriétés JSON telles que l'élément racine wrap, empêchent les valeurs NULL définies dans ObjectMapper ne fonctionnent plus.
Voici l'extrait de code
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="ignoreAcceptHeader" value="false" />
<property name="mediaTypes" >
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>
et le convertisseur JSON
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customJacksonObjectMapper"/>
<property name="supportedMediaTypes" value="application/json"/>
</bean>
Code du mappeur d'objets
public class CustomJacksonObjectMapper extends ObjectMapper {
@SuppressWarnings("deprecation")
public CustomJacksonObjectMapper() {
super();
final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRITE_NULL_PROPERTIES, false);
this.setDeserializationConfig(this.getDeserializationConfig().withAnnotationIntrospector(introspector));
this.setSerializationConfig(this.getSerializationConfig().withAnnotationIntrospector(introspector));
}
}
Version de Jackson
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.7</version>
</dependency>
Quel pourrait être le problème? Tous les indicateurs sont appréciés.
_ {Avertissement: je ne peux pas déterminer pourquoi le code en question ne fonctionne pas, mais je peux reproduire le problème. Cette réponse fournit une approche alternative qui fonctionne pour moi.} _
Cela pourrait être un bogue, car je peux reproduire le problème avec les deux avec une configuration explicite:
<bean id="jacksonObjectMapper" class="com.demo.CustomJacksonObjectMapper"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper"/>
<property name="supportedMediaTypes" value="application/json"/>
</bean>
et via le mvc: convertisseur de messages:
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
où les deux me donnent {"foo":null,"bar":"bar"}
lors de l'utilisation de la classe d'exemple
Demo.Java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.codehaus.jackson.annotate.JsonProperty;
@Controller
@RequestMapping("/data")
public class Data {
@RequestMapping
@ResponseBody
public Dummy dataIndex() {
return new Dummy();
}
public class Dummy {
String foo = null;
@JsonProperty
public String foo() {
return foo;
}
String bar = "bar";
@JsonProperty
public String bar() {
return bar;
}
}
}
Cependant, j’aurais pensé que la méthode mvc: message-converter fonctionnerait, uniquement parce que j’ai rencontré des problèmes annulant l’enregistrement du bean par défaut exécuté par <mvc:annotation-driven/>
(voir Web MVC Framework ) et utilisant la méthode imbriquée. la configuration est préférée (?).
Peut-être que le support Jackson 2 a causé des problèmes de compatibilité avec les versions antérieures de Jackson 1?
Cependant, le passage à MappingJackson2HttpMessageConverter (pris en charge dans Spring 3.1.2 et Spring 3.2), permet à I am de modifier la configuration de ObjectMapper afin de ne pas écrire les valeurs nulles et d'envelopper la sortie JSON ... mais uniquement lors de l'utilisation de la configuration dans le <mvc:message-converters/>
!
Je reçois {"Dummy":{"bar":"bar"}}
avec les modifications suivantes:
pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.1.0</version>
</dependency>
CustomJacksonObjectMapper.Java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import static com.fasterxml.jackson.annotation.JsonInclude.*;
public class CustomJacksonObjectMapper extends ObjectMapper {
public CustomJacksonObjectMapper() {
super();
this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
this.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
this.setSerializationInclusion(Include.NON_NULL);
}
}
Demo.Java bascule vers la nouvelle structure de paquet pour Jackson 2
import com.fasterxml.jackson.annotation.JsonProperty;
demo-servlet.xml
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Enfin, selon le SerializationConfig.Feature
documentation, la fonctionnalité WRITE_NULL_PROPERTIES
est obsolète <v2.0 et vous devriez quand même utiliser SerializationConfig.setSerializationInclusion()
. Je suppose que c'est pourquoi la @SuppressWarnings("deprecation")
existe dans votre code. Dans Jackson> = v2.0, il a été supprimé, d'où le changement de code dans CustomJacksonObjectMapper.Java example.
Configuration d'ObjectMapper dans Spring propose une solution alternative.
J'espère que ça aide!
Même si celui-ci est un ancien post, j'ai mis en phase un problème similaire (peut-être même le même?). Je l'ai retrouvé dans le problème suivant (et cela pourrait aider les autres):
Pour résoudre le problème, je peux soit:
Dans mon cas, j’ai opté pour la solution 3, car nous avons besoin de deux versions différentes et que l’annotation supplémentaire n’ajoute pas beaucoup de travail.