当子属性具有尾随空值时,Jackson反序列化将中止

时间:2012-11-25 14:35:32

标签: java json serialization null jackson

当发送一个由杰克逊反序列化的JSON时,似乎如果子元素的最后一个值为null,杰克逊将中止反序列化。


为:

如果我将此JSON发送到我的接收方(下方),则映射的Content对象将为null,因为反序列化在image停止:

{"user":{"id":"1", "token":"ABC", "image":null},"content":{"id":"2"}}

不可

如果我这样发送,image仍会根据需要设置null值,但Content对象将使用其ID创建:

{"user":{"id":"1", "image":null, "token":"ABC"},"content":{"id":"2"}}

对我来说这看起来像个错误..?!


简单接收器

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Response create(UserContent source) {
        UserContent dbResult = manager.create(source);
        return Response.status(200)
                .entity(dbResult.getId().toString()).build();
}

串行

 public static String objectToString(Object object) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"));

        Writer strWriter = new StringWriter();
        try {
            mapper.writeValue(strWriter, object);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        String userDataJSON = strWriter.toString();

        return userDataJSON;
    }

我可以设置我的ObjectMapper来将所有null序列化为""或发送端的空对象吗?

如果我将具有UserContent属性的null对象传递给上述方法,则生成的JSON将具有null值,如上例所示,并且列表的最后一项应该具有值null,反序列化将中止,导致后端出现NullPointerExceptions。


编辑 - UserContent类:

@Entity
@Table(name = "user_content")
@XmlRootElement
public class UserContent extends org.springframework.data.jpa.domain.AbstractPersistable<Long> {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    @Fetch(FetchMode.JOIN)
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "content_post_id", nullable = false)
    @Fetch(FetchMode.JOIN)
    private Contentcontent;

    // more properties...
}

我们的依赖项:

<properties>
    <jersey-version>1.14</jersey-version>
</properties>
            <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.5</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>${jersey-version}</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>${jersey-version}</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>${jersey-version}</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-multipart</artifactId>
        <version>${jersey-version}</version>
    </dependency>


    <dependency>
        <groupId>com.sun.jersey.jersey-test-framework</groupId>
        <artifactId>jersey-test-framework-grizzly2</artifactId>
        <version>${jersey-version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-servlet</artifactId>
        <version>${jersey-version}</version>
        <scope>test</scope>
    </dependency>

2 个答案:

答案 0 :(得分:0)

我们现在针对这个奇怪的行为提出的解决办法是忽略序列化上的所有空值,方法是配置ObjectMapper

mapper.setSerializationInclusion(Inclusion.NON_NULL);

我们可以做到,因为我们控制双方。如果我们公开提供REST服务,我仍然很好奇如何实际处理传入的空值值,如上所述。

答案 1 :(得分:-2)

假设你正在使用运动衫。您可以尝试在服务器端用Genson替换jackson,它应该可以解决您的问题。确实,它看起来像一个bug。一定要删除jackson和jersey-json。您不需要任何配置来启用Genson的json支持,只需将jar放在类路径中即可。