I've been developing an application that provides a REST service. I have some tested code that I run against it to see if it works okay.
When running it against the application deployed on my local Weblogic development server, it works fine.
However, when I deployed it on another Weblogic server on a Red Hat machine, I get 400 Bad Request errors.
Here is the client code I'm using to test the service:
Client client = Client.create();
//WebResource webResource = client.resource("http://10.1.1.2:7001/NotificationFramework/rest/notifications/createNotification");
WebResource webResource = client.resource("http://rhvm:7003/NotificationFramework/rest/notifications/createNotification");
ClientResponse clientResponse = webResource.type("application/json").post(ClientResponse.class, testJsonObject.toString());
JSONObject response2 = new JSONObject(clientResponse.getEntity(String.class));
System.out.println(response2);
The commented line is the one on my local machine.
Here is the response I'm getting:
An error occurred: Server returned HTTP response code: 400 for URL: http://rhvm:7003/NotificationFramework/rest/notifications/createNotification
And here is an excerpt of the code providing the REST service:
@Path("/notifications")
public class RestServices {
@POST
@Path("/createNotification")
@Consumes( {MediaType.APPLICATION_JSON} )
@Produces( {MediaType.APPLICATION_JSON} )
public static NotificationResponse createNotification(JAXBElement<Notification> n) {
// do some stuff
return notificationResponse;
}
I've already tried putting an extra / on the end. And I've tested it with the RESTClient add-on for Firefox and I get the exact same behaviour.
Any help would be greatly appreciated.
Thanks in advance.
// Edit
I discovered that it's something to do with the JAXBElement.
The following services works:
@POST
@Path("testRest3")
@Consumes( {MediaType.APPLICATION_JSON} )
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest3() {
logger.info("yo3");
return new NotificationResponse(101, "yo");
}
but the following doesn't:
@POST
@Path("testRest4")
@Consumes( {MediaType.APPLICATION_JSON} )
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest4(JAXBElement<Notification> n) {
logger.info("yo4");
return new NotificationResponse(101, "yo");
}
I checked the Notification class as recommended by pestrella and found that @XmlRootElement was missing. I added this but this still hasn't fixed the problem. I'm not sure if it should be @Xml.. but I'm new to this. Following the tutorial from vogella.
Here is my Notification class:
@XmlRootElement
public class Notification {
private int applicationId;
private int notificationId;
private int priority;
private String message;
private String detail;
private String appUrl;
// methods and stuff
}
And here is the body as submitted with the RESTClient add-on for Firefox:
{"appUrl":"","message":"my message","notificationId":1110001,"detail":"my detail","priority":3,"applicationId":111}
A
400
response in this instance can indicate some sort of error while unmarhsalling thePOST
body.Using the
@XMLRootElement
is fine. However, you might have problems getting JAXB to unmarshal to primitive types (depends on what version you've got).The safest way to get JAXB to unmarshal your
Notification
object is to use theInteger
type instead of a primitiveint
type.Also, you should not need to wrap the
Notification
object withJAXBElement
if you are using the@XmlRootElement
annotation. Try removing theJAXBElement
wrapper:If the problem persists, then you can always use a
MessageBodyReader
to unmarshal request bodies manually.The typical way to do this for JSON request bodies is to implement
MessageBodyReader
and use a JSON parser of your choice, like Gson or Jackson.