web-dev-qa-db-ja.com

Spring REST Service:json応答でnullオブジェクトを削除するように設定する方法

JSON応答を返すSpring Webサービスがあります。ここにある例を使用してサービスを作成しています: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

Jsonが返される形式は次のとおりです。{"name":null、 "staffName":["kfc-kampar"、 "smith"]}

返された応答からnullオブジェクトを削除して、次のようにします。{"staffName":["kfc-kampar"、 "smith"]}

私はここで尋ねられた同様の質問を見つけましたが、私は解決策を得ることができました.

SpringでのObjectMapperの構成

スプリング注釈ベースの構成を使用しながらMappingJacksonHttpMessageConverterを構成する方法?

mvc 3のスプリングで機能しないjacksonObjectMapperの設定

json応答で「null」オブジェクトを返さないようにspring mvc 3を設定する方法?

Spring configure @ResponseBody JSON format

Jackson + Spring3.0.5カスタムオブジェクトマッパー

これらのソースや他のソースを読んで、Spring 3.1とmvc-annotation内で構成できるメッセージコンバーターを使用することが、最もクリーンな方法であると考えました。私の更新された春の設定ファイルは次のとおりです。

<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>

サービスクラスはmkyong.comサイトで指定されているものと同じですが、Shop name変数の設定をコメントアウトしているため、nullです。

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

私が使用しているジャクソン瓶は、jackson-mapper-asl 1.9.0およびjackson-core-asl 1.9.0です。これらは、mkyong.comからダウンロードしたspring-jsonプロジェクトの一部として提供される、pomに追加した唯一の新しいjarです。

プロジェクトは正常にビルドされますが、ブラウザからサービスを呼び出すと、同じこと、つまり{"name":null、 "staffName":["kfc-kampar"、 "smith"]}が取得されます。

私の設定のどこが間違っているのか教えていただけますか?

私は他のいくつかのオプションを試しましたが、正しい形式でjsonを返すことができた唯一の方法は、オブジェクトマッパーをJSONControllerに追加し、「getShopInJSON」メソッドが文字列を返すようにすることです.

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

これで、サービスを呼び出すと、期待されるものが得られます。つまり、{"staffName":["kfc-kampar"、 "cronin"]}

@JsonIgnoreアノテーションを使用して機能させることもできましたが、このソリューションは私には適していません。

なぜコードでは機能するのに構成では機能しないのか理解できないので、どんな助けも素晴らしいでしょう。

53
mikec

Jackson 2.0以降では、 JsonInclude を使用できます

@JsonInclude(Include.NON_NULL)
public class Shop {
    //...
}
75
Walery Strauch

Jacksonが使用されているため、それをJacksonプロパティとして設定する必要があります。 Spring Boot RESTサービスの場合、application.propertiesまたはapplication.ymlで設定する必要があります。

spring.jackson.default-property-inclusion = NON_NULL

ソース

59
Luís Soares
_@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
public class Shop {
    //...
}
_

jackson 2.0以降では@JsonInclude(Include.NON_NULL)を使用します

これにより、空のオブジェクトとnullオブジェクトの両方が削除されます。

8
Jekin Kalariya

Jackson 2を使用している場合、メッセージコンバータータグは次のとおりです。

<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>
5
Eduardo

Jackson 2.0の時点で、@JsonSerialize(include = xxx)は廃止され、@JsonInclude

5
A B

バージョン1.6以降、新しい注釈JsonSerializeが追加されました(たとえば、バージョン1.9.9)。

例:

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

デフォルト値は常にです。

古いバージョンでは、JsonWriteNullPropertiesを使用できますが、これは新しいバージョンでは非推奨です。例:

@JsonWriteNullProperties(false)
public class Test{
    ...
}
4
grep

すべての非XML構成の人々:

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

Jacksonの古いバージョンでは JsonWriteNullProperties を使用できます。

Jackson 1.9+の場合、 JsonSerialize.include

1
user647772

Springコンテナを構成することで解決策を見つけましたが、それはまだ私が望んでいたものではありません。

Spring 3.0.5にロールバックして削除し、その場所で設定ファイルを次のように変更しました。

    <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>

これはもちろん、他の質問で与えられた回答に似ています。

mvc 3のスプリングで機能しないjacksonObjectMapperの設定

重要なことは、mvc:annotation-drivenとAnnotationMethodHandlerAdapterを同じコンテキストで使用できないことです。

ただし、Spring 3.1およびmvc:annotation-drivenで動作させることはできません。 mvc:annotation-drivenとそれに付随するすべての利点を使用するソリューションは、はるかに優れていると思います。誰かがこれを行う方法を教えてくれたら、それは素晴らしいことです。

1
mikec

spring.jackson.default-property-inclusion=non_nullオプションは最も単純なソリューションであり、うまく機能します。

ただし、コードのどこかにWebMvcConfigurerを実装する場合は注意が必要です。プロパティソリューションが機能せず、次のようにコードでNON_NULLシリアル化を設定する必要があります。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    // some of your config here...

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(objectMapper);
        converters.add(jsonConverter);
    }
}
0
Zantsu