Sometimes JAR-RS clients are sending wrong syntactical request body. The server should response with HTTP status 400 (Bad Request), but it responses with HTTP status 500 (Internal Server Error).
Code:
JAX-B model class:
@XmlRootElement(namespace = "http://www.test.com/test")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class TestModel {
@XmlElement
private String id;
}
JAX-RS resource class:
@Path("test")
public class TestResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void create(TestModel testModel) {
// some code
}
}
CXF configuration:
<jaxrs:server address="/rest" id="test" staticSubresourceResolution="true">
<jaxrs:serviceBeans>
<ref bean="testResource" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
Example:
Request body:
{"id2": "test"}
The id2
is wrong, so client should get a HTTP status 400, but it gets HTTP status 500.
Server log:
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "id2" (class test.TestModel), not marked as ignorable (one known property: "id"])
at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1@6f30793d; line: 1, column: 10] (through reference chain: test.TestModel["id2"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)
at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:839)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1045)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1352)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1330)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:264)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1470)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:912)
at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:811)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1343)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1294)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:826)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:789)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:212)
... 68 more
Is there a way to configure Jackson and/or CXF to return HTTP status 400 for wrong syntactical request body without schema validation or bean validation?
If the JAX-RS resource method’s return type is void, a response code of 204, “No Content,” is returned. This is the case with our update () and delete () methods. The HTTP specification is pretty consistent for the PUT, POST, GET, and DELETE methods. If a successful HTTP response contains a message body, 200, “OK,” is the response code.
An HTTP 500 error code means we have an internal server issue. The client made a good request, but the server didn’t complete it and something is wrong with the server. The HTTP status code denotes a general server problem and it should be addressed ASAP. It’s recommended to contact your web host to solve this issue.
JAX-RS exception hierarchy BadRequestException is used when the client sends something to the server that the server cannot interpret. The JAX-RS runtime will actually throw this exception in certain scenarios. The most obvious is when a PUT or POST request has submitted malformed XML or JSON that the MessageBodyReader fails to parse.
JAX-RS 2.0 has added a nice exception hierarchy for various HTTP error conditions. So, instead of creating an instance of WebApplicationException and initializing it with a specific status code, you can use one of these exceptions instead. We can change our previous example to use javax.ws.rs.NotFoundException:
The problem is that exceptions that aren't mapped to response (by way of ExceptionMapper
s), translate to a general server error response, as the runtime has no idea what to do with the exception.
The jackson-jaxrs-provider
module has ExceptionMapper
s to handle the Jackson base exception class JsonMappingException
and JsonParseException
. The mappers are JsonMappingExceptionMapper
and JsonParseExceptionMapper
, respectively. These mappers will map the exception to a 400 response along with the exception message as the response body. If you do not like this response body, you can just write your own mapper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With