Hello,
I'm hoping someone can help me with something.
I'm evaluating the suitability of Camel 2.15 for building a rest API with
JSON and have run into a problem when marshalling POJOs when the HTTP
response code is not 200 Ok.
I've opted to use the Camel Spark Rest component, and have modified the
example code to test out error handling.
To facilitate discussion and avoid sending pages of code I've included the
modified version of the UserRouteBuilder.java example code below that I've
used to replicate this problem:
package org.apache.camel.example.spark;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.rest.RestBindingMode;
import org.apache.camel.Exchange;
/**
* Define REST services using the Camel REST DSL
*/
public class UserRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
// configure we want to use spark-rest as the component for the
rest DSL
// and we enable json binding mode
restConfiguration().component("spark-rest").bindingMode(RestBindingMode.json).dataFormatProperty("prettyPrint",
"true");
// this user REST service is json only
rest("/user").consumes("application/json").produces("application/json")
.get("/view/{id}").outType(User.class)
.to("direct:getUser");
from("direct:getUser")
.to("bean:userService?method=getUser(${header.id})")
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400));
}
}
When run from the Spark Rest Tomcat example (using Jetty) the response
output is the User Object hash code
(org.apache.camel.example.spark.User@4ba6cfd4 for example) instead of the
JSON string for the object.
If I modify the code and remove the call to setHeader, or set the response
code to 200 I get the object as expected.
I have tested manually marshalling, which works if I run it as follows:
...
import org.apache.camel.model.dataformat.JsonLibrary;
...
public void configure() throws Exception {
...
from("direct:getUser")
.to("bean:userService?method=getUser(${header.id})")
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.marshal().json(JsonLibrary.Jackson);
}
}
I've also re-worked the code to throw an Exception and handle this using
the onException method but again encounter the same problem, which can only
be resolved by manually marshalling.
Since I plan on having the API respond using other HTTP response codes
(400, 404 etc), with JSON messages containing the problem details how am I
supposed to set the response code and have objects marshalled automatically?
The docs only cover responding in this circumstance in plain text, but as
this will be an API I need to respond with a more detailed messages and
would hate to have to manually marshal the responses.
I'm assuming I'm missing some thing here, can anyone please help?
Thanks,
Brian