在Jersey中返回JSON或XML for Exceptions

Dom*_*nic 11 rest error-handling json exception jersey

我的目标是在找不到对象时在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");
     }

}
Run Code Online (Sandbox Code Playgroud)

我的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());
    }

}
Run Code Online (Sandbox Code Playgroud)

ErrorBean如下:

@XmlRootElement(name = "error")
public class ErrorBean {

    private String errorMsg;
    private int errorCode;

        //no-arg constructor, property constructor, getter and setters
        ...

}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试这个时,我总是收到204 No Content的回复.我已经乱砍了,如果我返回一个字符串并指定mime类型,这可以正常工作:

public NotFoundException(String message) {
    super(Response.status(Response.Status.NOT_FOUND).
            entity(message).type("text/plain").build());
}
Run Code Online (Sandbox Code Playgroud)

我也尝试将ErrorBean作为资源返回.这很好用:

{"errorCode":404,"errorMsg":"Location 1 is not found!"}
Run Code Online (Sandbox Code Playgroud)

Dom*_*nic 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)"
}
Run Code Online (Sandbox Code Playgroud)