2012-10-03 1 views
35

Ich habe einen Spring-Webservice, der eine JSON-Antwort zurückgibt. Ich bin mit dem hier gegebenen Beispiel den Dienst zu erstellen: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/Spring REST Service: Wie konfiguriert man, um Nullobjekte in JSON-Antwort zu entfernen

Das Format der json zurückgegeben wird in ist: { "name": null, "staffName": [ "kfc-Kampar", "smith" ]}

ich irgendwelche null Objekte aus der zurückgegebene Antwort entfernen möchten, so dass es wie folgt aussieht: { "staffName": [ "kfc-Kampar", "smith"]}

ich habe ähnliche gefunden Fragen, die hier gestellt wurden, aber ich war in der Lage, eine Lösung zu bekommen, die zB funktioniert

Configuring ObjectMapper in Spring

How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration?

configuring the jacksonObjectMapper not working in spring mvc 3

how to configure spring mvc 3 to not return "null" object in json response?

Spring configure @ResponseBody JSON format

Jackson+Spring3.0.5 custom object mapper

Beim Durchlesen dieser und anderer Quellen habe ich festgestellt, dass Spring 3.1 und die Nachrichtenkonverter, die in der mvc-Annotation konfiguriert werden können, am saubersten zu erreichen sind. Meine aktualisiert Frühjahr Konfigurationsdatei ist:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd 
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> 

<context:component-scan base-package="com.mkyong.common.controller" /> 

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
      <property name="prefixJson" value="true" /> 
      <property name="supportedMediaTypes" value="application/json" /> 
      <property name="objectMapper"> 
       <bean class="org.codehaus.jackson.map.ObjectMapper"> 
        <property name="serializationInclusion" value="NON_NULL"/> 
       </bean> 
      </property> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

Die Service-Klasse ist die gleiche wie auf der mkyong.com Website gegeben, außer ich aus der Einstellung des Shop-Name Variable kommentiert, so dass es also

null ist
@Controller 
@RequestMapping("/kfc/brands") 
public class JSONController { 
    @RequestMapping(value="{name}", method = RequestMethod.GET) 
    @ResponseStatus(HttpStatus.OK) 
    public @ResponseBody Shop getShopInJSON(@PathVariable String name) { 
     Shop shop = new Shop(); 
     //shop.setName(name); 
     shop.setStaffName(new String[]{name, "cronin"}); 
     return shop; 
    } 
} 

Die Jackson Gläser, die ich benutze, sind jackson-mapper-asl 1.9.0 und jackson-core-asl 1.9.0. Dies sind die einzigen neuen Jars, die ich zum Pom hinzugefügt habe, die im Rahmen des Spring-JSON-Projekts zur Verfügung gestellt wurden, das ich von mkyong.com heruntergeladen habe.

Das Projekt baut erfolgreich, aber wenn ich den Dienst über den Browser aufrufen ich immer noch die gleichen, dh { "name": null, "staffName": [ "kfc-Kampar", "smith"]}

Kann mir jemand sagen, wo ich mit meiner Konfiguration falsch liege?

Ich habe mehrere andere Optionen ausprobiert, aber die einzige Möglichkeit, die JSON im richtigen Format zurückzugeben, ist, den Object Mapper zum JSONController hinzuzufügen und die "getShopInJSON" -Methode eine Zeichenfolge zurückgeben, dh

public @ResponseBody String getShopInJSON(@PathVariable String name) throws JsonGenerationException, JsonMappingException, IOException { 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); 

    Shop shop = new Shop(); 
    //shop.setName(name); 
    shop.setStaffName(new String[]{name, "cronin"}); 
    String test = mapper.writeValueAsString(shop); 
    return test; 
} 

Nun, wenn ich den Dienst rufe ich die erwartete bekommen also { "staffName": [ "kfc-Kampar", "cronin"]}

ich habe auch in der Lage gewesen, um es an die Arbeit Verwenden Sie die @ JsonIgnore Annotation, aber diese Lösung ist nicht für mich geeignet.

Ich verstehe nicht, warum es in Code funktioniert, aber nicht in der Konfiguration, also wäre jede Hilfe fantastisch.

+1

Für mich ist es Frühling schien nicht das Mapper-Objekt, das in der Contex-Datei definiert, i mit Debug-Feder geprüft ruft 'setSerializationInclusion()' Methode für Mapper-Objekt in xml definiert – Elbek

+1

Ya, so verstehe ich es auch. Der Objekt-Mapper scheint korrekt konfiguriert zu sein, er wird nur nicht im Spring-Container verwendet. – mikec

Antwort

1

Ich habe eine Lösung durch die Konfiguration des Spring-Containers gefunden, aber es ist immer noch nicht genau das, was ich wollte.

Ich rollte zurück nach Spring 3.0.5, entfernt und in seinem Platz änderte ich meine Config-Datei:

<bean 
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <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="org.codehaus.jackson.map.ObjectMapper" /> 
<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" 
    factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" /> 
<bean 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject" ref="jacksonSerializationConfig" /> 
    <property name="targetMethod" value="setSerializationInclusion" /> 
    <property name="arguments"> 
     <list> 
      <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value> 
     </list> 
    </property> 
</bean> 

Dies ist natürlich ähnlich wie Antworten in anderen Fragen gegeben z.B.

configuring the jacksonObjectMapper not working in spring mvc 3

Die wichtige Sache zu beachten ist, dass mvc: Annotation-driven und AnnotationMethodHandlerAdapter können nicht im gleichen Kontext verwendet werden.

Ich bin immer noch nicht in der Lage, es funktioniert mit Spring 3.1 und MVC: Annotation-driven obwohl. Eine Lösung, die mit mvc: annotation-driven arbeitet und all die damit verbundenen Vorteile wäre viel besser, denke ich. Wenn mir jemand zeigen könnte, wie das geht, wäre das großartig.

5

Wenn Sie Jackson 2 verwenden, wird die Nachricht-Wandler tag:

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="prefixJson" value="true"/> 
      <property name="supportedMediaTypes" value="application/json"/> 
      <property name="objectMapper"> 
       <bean class="com.fasterxml.jackson.databind.ObjectMapper"> 
        <property name="serializationInclusion" value="NON_NULL"/> 
       </bean> 
      </property> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 
50

Seit Jackson 2.0 Sie JsonInclude

@JsonInclude(Include.NON_NULL) 
public class Shop { 
    //... 
} 
2

Seit der Version 1.6 haben wir neue Annotation JsonSerialize (in Version verwenden können 1.9.9 zum Beispiel).

Beispiel:

@JsonSerialize(include=Inclusion.NON_NULL) 
public class Test{ 
... 
} 

Der Standardwert ist IMMER.

In alten Versionen können Sie JsonWriteNullProperties verwenden, was in neuen Versionen veraltet ist. Beispiel:

ObjectMapper objMapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); 
HttpMessageConverter msgConverter = new MappingJackson2HttpMessageConverter(objMapper); 
restTemplate.setMessageConverters(Collections.singletonList(msgConverter)); 
+0

'' @JsonSerialize (include = Inclusion.NON_NULL) '' veraltet – cheloncio

5

Ab Jackson 2,0 @JsonSerialize(include = xxx) hat sich für @JsonInclude

3

Für alle Nicht-XML-Konfigurations Leute veraltet Entfernen Sie sowohl leere als auch Null-Objekte

2
@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY) 
public class Shop { 
    //... 
} 

Dies wird:

@JsonWriteNullProperties(false) 
public class Test{ 
    ... 
} 
19

Da Jackson verwendet wird, müssen Sie das als Jackson-Eigenschaft konfigurieren.Im Fall von Spring-Boot-REST-Service, haben Sie sie konfigurieren in application.properties:

spring.jackson.default-property-inclusion=NON_NULL 

source

+2

unglücklicherweise löschte ein Moderator meine Antwort behauptet, dass diese Fragen wiederholt wurden. Aber er ist ein Python-Typ und konnte vielleicht nicht sehen, dass es sich um verschiedene Java-Spring-Fragen handelte (eine für Spring MVC, andere für Spring REST). Er hat den in der wichtigsten Frage gelöscht. BTW, es gibt keine Möglichkeit zu tailer. Die Antworten sind gleich. Die Bibliothek ist dieselbe (Jackson). Ich werde es erneut versuchen, um der Community zu helfen. –

+12

Der Name der Eigenschaft wurde in 'spring.jackson.default-property-inclusion = NON_NULL' geändert. Funktioniert gut! – Miguel

Verwandte Themen