我的目标是在找不到对象时在404上返回带有描述性消息的错误bean,并返回所请求的相同MIME类型。
我有一个查找资源,它将基于URI返回XML或JSON中的指定对象(我已经设置了com.sun.jersey.config.property.resourceConfigClass servlet参数,因此我不需要Accept标头。我的JAXBContextResolver在其类型列表中有ErrorBean.class,并为此类返回正确的JAXBContext,因为我可以在日志中看到。)
例如:http://foobar.com/rest/locations/1.json
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Location getCustomer(@PathParam("id") int cId) {
//look up location from datastore
....
if (location == null) {
throw new NotFoundException("Location" + cId + " is not found");
}
}
我的NotFoundException看起来像这样:
public class NotFoundException extends WebApplicationException {
public NotFoundException(String message) {
super(Response.status(Response.Status.NOT_FOUND).
entity(new
ErrorBean(
message,
Response.Status.NOT_FOUND.getStatusCode()
)
.build());
}
}
ErrorBean如下:
@XmlRootElement(name = "error")
public class ErrorBean {
private String errorMsg;
private int errorCode;
//no-arg constructor, property constructor, getter and setters
...
}
然而,当我尝试这个时,我总是得到 204 No Content 响应。我已经乱砍了,如果我返回一个字符串并指定mime类型,这可以正常工作:
public NotFoundException(String message) {
super(Response.status(Response.Status.NOT_FOUND).
entity(message).type("text/plain").build());
}
我也尝试将ErrorBean作为资源返回。这很好用:
{"errorCode":404,"errorMsg":"Location 1 is not found!"}
答案 0 :(得分:9)
对于那些在未来有类似问题的人......
原来我的代码还可以。我把头发拉了出来,所以我重写了这个模块,但仍然没有到达任何地方。我的浏览器只会坐在那里永远挂起。我开始使用LiveHTTPHeaders(firefox附加组件)检查标头,并注意到发生这种情况时Content-Length大于零。然后我用hurl.it进行测试,发现身体正常恢复。浏览器可以很好地处理XML响应,但是不会显示JSON(因此挂起)。这对我来说很好,因为这纯粹是用于应用程序消费的API而不是用户。有关Jersey wiki的映射异常的信息。
HTTP/1.1 404 Not Found
Content-Type: application/json
Date: Fri, 21 May 2010 06:39:28 GMT
Server: Google Frontend
Cache-Control: private, x-gzip-ok=""
Transfer-Encoding: chunked
{
"errorCode": "404",
"errorMsg": "Could not retrieve entity of kind Location with key Location(10)"
}