When sending out a JSON to be deserialized by Jackson it seems that if the last value of a subelement is null, Jackson will abort the deserialization.
Bad:
If I send this JSON to my receiver (below), the mapped Content object will be null, because the deserialization stops at image:
{"user":{"id":"1", "token":"ABC", "image":null},"content":{"id":"2"}}
Good:
If I send it like this, image will still have the null value as desired but the Content object will be created with its id:
{"user":{"id":"1", "image":null, "token":"ABC"},"content":{"id":"2"}}
This looks like a bug to me..?!
simple Receiver:
@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();
}
Serializer
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;
}
Can I set up my ObjectMapper to serialize all null as "" or empty Object on my sending side?
If I pass a UserContent object with a null property to the above method, the resulting JSON will have null values like the example above and should the last item of a list have the value null, deserialization will abort causing NullPointerExceptions in my backend.
edit – the UserContent class:
@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...
}
our dependencies:
<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>
Our solution right now for this strange beahavior is to ignore all null values on Serialization by configuring the
ObjectMapper:Which we can do as we controle both sides. I’m still curious about how to actually handle an incoming null value constelation as described above in case we make the REST service publicly available.