杰克逊忽略了ACCEPT_EMPTY_STRING_AS_NULL_OBJECT

时间:2016-05-16 08:05:24

标签: angularjs json spring-mvc jackson

我需要在Spring MVC中将空字符串("")视为null。这是因为我发现当我编辑一个最初为undefined的表单字段(使用Angular的ng-model)时,将其擦除为空白,Angular会将该bean属性作为空字符串发送。如果我没有触及这样的空值,它将不会在JSON有效载荷中发送,因此被视为空。

我在Spring的上下文中使用ACCEPT_EMPTY_STRING_AS_NULL_OBJECT DeserializationFeature配置了Jackson。配置如下:

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <constructor-arg>
        <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
            <property name="featuresToDisable">
                <array>
                    <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS" />
                </array>
            </property>
            <property name="featuresToEnable">
                <array>
                    <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT" />
                    <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING" />
                    <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.READ_ENUMS_USING_TO_STRING" />
                    <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT" />
                </array>
            </property>
            <property name="serializationInclusion">
                <util:constant static-field="com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL" />
            </property>
        </bean>
    </constructor-arg>
    <property name="supportedMediaTypes">
        <array>
            <value>application/json</value>
        </array>
    </property>
</bean>

但是,看起来它将空字符串解码为空字符串而不是null。我已调试,我可以在有效负载中看到“”。以下是管理页面中的示例

{
   "id":"ADMIN.NOTIFIER_SMTP",
   "host":"aa.bb.cc",
   "protocol":"POP",
   "securityProtocol":"PLAIN",
   "username":"", <----- shall be null on server, I don't care about client
   "passwordSet":false
}

问题是:我的配置有问题吗?我怎么告诉杰克逊把空视为空?

2 个答案:

答案 0 :(得分:1)

可能是您要编写CustomObjectMapper

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="custom.CustomObjectMapper"/>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

并在其中添加上述反序列化程序。

答案 1 :(得分:0)

Jackson会为其他对象提供null,但对于String,它将提供空String。

但您可以使用Custom JsonDeserializer来执行此操作:

   class CustomDeserializer extends JsonDeserializer<String> {

@Override
public String deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
    JsonNode node = jsonParser.readValueAs(String.class);
    if (node.asText().isEmpty()) {
        return null;
    }
    return node.toString();
}}

在课堂上,你必须将它用于位置字段:

class EventBean {
    public Long eventId;
    public String title;

    @JsonDeserialize(using = CustomDeserializer.class)
    public String location;
}