funseiki funseiki - 16 days ago 6
JSON Question

Apache CXF default POST request body with Jackson

In an Apache CXF JAX-RS project I'm working on, I've configured the JSON provider to be Jackson.

This generally works, but I'd like the

POST
request body to always be not
null
, so that if a client sends a request with an empty body (no JSON
{}
), I'd still get a default POJO.

E.g.

CXF side:

@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Path("/foo")
public Response postFoo(FooObj foo) {
if (foo == null)
return Response.ok("No foo");
else
return Response.ok("Foo found");
}


Client side:

curl -XPOST -H "Content-Type: application/json" "http://localhost/foo"
"No Foo" // Though we'd like to see "Foo found"

Answer

It is not possible to get a default POJO with an empty response using CXF+Jackson. You can decide between null or NoContentException

The answer is not obvious. The JAX-RS specification 3.3.2.1 stablish that the conversion between an entity body and a Java type is the responsibility of an entity provider. Interface MessageBodyReader maps the entity body to Java

T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,String> httpHeaders,
     InputStream entityStream)
       throws IOException, WebApplicationException

Read a type from the InputStream.

In case the entity input stream is empty, the reader is expected to either return a Java representation of a zero-length entity or throw a NoContentException in case no zero-length entity representation is defined for the supported Java type. A NoContentException, if thrown by a message body reader while reading a server request entity, is automatically translated by JAX-RS server runtime into a BadRequestException wrapping the original NoContentException and rethrown for a standard processing by the registered exception mappers.

It is not clear for me what is the meaning of "no zero-length entity". In any case, it is responsability of the entity provider, in your case Jackson.

Read this post of Jackson's team discussing about how to deal with zero-length entities in JacksonJsonProvider MessageBodyReader

The readFrom() method in ProviderBase returns null when it encounters an empty stream. According to both the javadoc for MessageBodyReader, and JSR311, this is not allowed.

Jackson team consider returning null always is a bug, and reading the new specification JAX-RS2.0, they add a new parameter in Jackson 2.4.0

JaxRSFeature.ALLOW_EMPTY_INPUT

with default value true to be compatible with previous versions. When disabled it will raise an error. NoContentException for JAX-RS 2.x and IOException with 1.x

Comments