programing

Spring REST Service : JSON 응답에서 null 객체를 제거하도록 구성하는 방법

luckcodes 2021. 1. 16. 20:29

Spring REST Service : JSON 응답에서 null 객체를 제거하도록 구성하는 방법


json 응답을 반환하는 스프링 웹 서비스가 있습니다. 여기에 제공된 예제를 사용하여 서비스를 만듭니다. 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 구성

Spring 주석 기반 구성을 사용하는 동안 MappingJacksonHttpMessageConverter를 구성하는 방법은 무엇입니까?

Spring mvc 3에서 작동하지 않는 jacksonObjectMapper 구성

json 응답에서 "null"객체를 반환하지 않도록 spring mvc 3을 구성하는 방법은 무엇입니까?

Spring은 @ResponseBody JSON 형식을 구성합니다.

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 이름 변수의 설정을 주석 처리하여 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 jar는 jackson-mapper-asl 1.9.0 및 jackson-core-asl 1.9.0입니다. 이것들은 내가 mkyong.com에서 다운로드 한 spring-json 프로젝트의 일부로 제공되는 pom에 추가 한 유일한 새 항아리입니다.

프로젝트는 성공적으로 빌드되지만 브라우저를 통해 서비스를 호출하면 { "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 주석을 사용하여 작동시킬 수 있었지만이 솔루션은 나에게 적합하지 않습니다.

코드에서는 작동하지만 구성에서는 작동하지 않는 이유를 이해할 수 없으므로 어떤 도움도 환상적 일 것입니다.


Jackson 2.0부터 JsonInclude 를 사용할 수 있습니다 .

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

Jackson이 사용되고 있으므로이를 Jackson 속성으로 구성해야합니다. Spring Boot REST 서비스의 경우 application.properties또는 application.yml다음 에서 구성해야합니다 .

spring.jackson.default-property-inclusion = NON_NULL

출처


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

jackson 2.0 이상 사용 @JsonInclude(Include.NON_NULL)

이렇게하면 비어있는 개체와 null 개체가 모두 제거됩니다.


Jackson 2를 사용하는 경우 message-converters 태그는 다음과 같습니다.

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

Jackson 2.0 @JsonSerialize(include = xxx)부터는@JsonInclude


버전 1.6부터 새로운 주석 JsonSerialize가 있습니다 (예 : 버전 1.9.9).

예:

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

기본값은 항상입니다.

이전 버전에서는 새 버전에서 더 이상 사용되지 않는 JsonWriteNullProperties를 사용할 수 있습니다. 예:

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

XML이 아닌 모든 사용자를 위해 :

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

Spring 컨테이너 구성을 통해 해결책을 찾았지만 여전히 내가 원하는 것은 아닙니다.

I rolled back to Spring 3.0.5, removed and in it's place I changed my config file to:

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

This is of course similar to responses given in other questions e.g.

configuring the jacksonObjectMapper not working in spring mvc 3

The important thing to note is that mvc:annotation-driven and AnnotationMethodHandlerAdapter cannot be used in the same context.

I'm still unable to get it working with Spring 3.1 and mvc:annotation-driven though. A solution that uses mvc:annotation-driven and all the benefits that accompany it would be far better I think. If anyone could show me how to do this, that would be great.


You can use JsonWriteNullProperties for older versions of Jackson.

For Jackson 1.9+, use JsonSerialize.include.


Setting the spring.jackson.default-property-inclusion=non_null option is the simplest solution and it works well.

However, be careful if you implement WebMvcConfigurer somewhere in your code, then the property solution will not work and you will have to setup NON_NULL serialization in the code as the following:

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

ReferenceURL : https://stackoverflow.com/questions/12707165/spring-rest-service-how-to-configure-to-remove-null-objects-in-json-response