我一直在开发一个提供REST服务的应用程序。我有一些经过测试的代码,我对它运行以查看它是否正常工作。
当针对我本地Weblogic开发服务器上部署的应用程序运行它时,它可以正常工作。
但是,当我在Red Hat机器上的另一个Weblogic服务器上部署它时,我收到400个错误请求错误。
以下是我用来测试服务的客户端代码:
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);
注释行是我本地计算机上的行。
以下是我的回复:
An error occurred: Server returned HTTP response code: 400 for URL: http://rhvm:7003/NotificationFramework/rest/notifications/createNotification
以下是提供REST服务的代码的摘录:
@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;
}
我已经尝试过额外/最后。我已经使用Firefox的RESTClient插件测试了它,我得到了完全相同的行为。
非常感谢任何帮助。
提前致谢。
//编辑
我发现它与JAXBElement有关。
以下服务有效:
@POST
@Path("testRest3")
@Consumes( {MediaType.APPLICATION_JSON} )
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest3() {
logger.info("yo3");
return new NotificationResponse(101, "yo");
}
但以下情况并非如此:
@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");
}
我按照pestrella的建议检查了Notification类,发现缺少@XmlRootElement。我添加了这个,但这仍然没有解决问题。我不确定它是否应该是@Xml ..但我是新手。跟随vogella的tutorial。
这是我的通知类:
@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
}
这是与Firefox的RESTClient插件一起提交的正文:
{"appUrl":"","message":"my message","notificationId":1110001,"detail":"my detail","priority":3,"applicationId":111}
答案 0 :(得分:1)
此实例中的400
响应可以指示在取消POST
正文时出现某种错误。
使用@XMLRootElement
很好。但是,您可能无法使JAXB解组为原始类型(取决于您获得的版本)。
让JAXB解组您的Notification
对象的最安全方法是使用Integer
类型而不是原始int
类型。
@XmlRootElement
public class Notification {
private Integer applicationId;
/* and the rest... */
}
此外,如果使用Notification
注释,则不需要使用JAXBElement
包裹@XmlRootElement
对象。尝试删除JAXBElement
包装器:
@POST
@Path("testRest")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public static NotificationResponse testRest(Notification n) {
logger.info("yo!");
return new NotificationResponse(101, "yo");
}
如果问题仍然存在,那么您始终可以使用MessageBodyReader
手动解组请求正文。
为JSON请求主体执行此操作的典型方法是实现MessageBodyReader
并使用您选择的JSON解析器,如Gson或Jackson。
@Provider
@Consumes("application/json")
public class CustomJsonReader<T> implements MessageBodyReader<T> {
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations,MediaType mediaType) {
return true;
}
@Override
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException, WebApplicationException {
/* Convert the request body (passed in as InputStream) to a String.
* Here I'm using apache commons IOUtils to convert the input stream
*/
StringWriter writer = new StringWriter();
IOUtils.copy(entityStream, writer, "UTF-8");
String json = writer.toString();
/* Use JSON parser to unmarshal the JSON to a complex object */
return new Gson().fromJson(json, genericType);
}
}