我正在编写一个REST web应用程序(NetBeans 6.9, JAX-RS, TopLink Essentials),并试图返回JSON和HTTP状态代码。我已经准备好了代码,并在从客户端调用HTTP GET方法时返回JSON。从本质上讲:

@Path("get/id")
@GET
@Produces("application/json")
public M_機械 getMachineToUpdate(@PathParam("id") String id) {

    // some code to return JSON ...

    return myJson;
}

但是我还想返回一个HTTP状态码(500、200、204等)以及JSON数据。

我尝试使用HttpServletResponse:

response.sendError("error message", 500);

但这让浏览器认为这是一个“真正的”500,所以输出的网页是一个普通的HTTP 500错误页面。

我想返回一个HTTP状态代码,以便我的客户端JavaScript可以处理一些依赖于它的逻辑(例如,在HTML页面上显示错误代码和消息)。这是可能的还是HTTP状态码不应该用于这样的事情?


当前回答

如果您希望因为异常而更改状态代码,可以使用JAX-RS 2.0实现类似这样的ExceptionMapper。它为整个应用程序处理这种异常。

@Provider
public class UnauthorizedExceptionMapper implements ExceptionMapper<EJBAccessException> {

    @Override
    public Response toResponse(EJBAccessException exception) {
        return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
    }

}

其他回答

如果您的WS-RS需求引发错误,为什么不直接使用WebApplicationException呢?

@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("{id}")
public MyEntity getFoo(@PathParam("id") long id,  @QueryParam("lang")long idLanguage) {

if (idLanguage== 0){
    // No URL parameter idLanguage was sent
    ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
    builder.entity("Missing idLanguage parameter on request");
    Response response = builder.build();
    throw new WebApplicationException(response);
    }
... //other stuff to return my entity
return myEntity;
}

这里有一个例子:

@GET
@Path("retrieve/{uuid}")
public Response retrieveSomething(@PathParam("uuid") String uuid) {
    if(uuid == null || uuid.trim().length() == 0) {
        return Response.serverError().entity("UUID cannot be blank").build();
    }
    Entity entity = service.getById(uuid);
    if(entity == null) {
        return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + uuid).build();
    }
    String json = //convert entity to json
    return Response.ok(json, MediaType.APPLICATION_JSON).build();
}

看一下Response类。

请注意,您应该始终指定一个内容类型,特别是当您传递多个内容类型时,但如果每个消息都将表示为JSON,则可以使用@Produces("application/ JSON ")对方法进行注释。

另外,请注意,缺省情况下,如果http代码为400或更多,Jersey将覆盖响应体。

为了得到你指定的实体作为响应体,试着在你的web.xml配置文件的Jersey中添加以下初始化参数:

    <init-param>
        <!-- used to overwrite default 4xx state pages -->
        <param-name>jersey.config.server.response.setStatusOverSendError</param-name>
        <param-value>true</param-value>
    </init-param>

JAX-RS支持标准/自定义HTTP代码。参见ResponseBuilder和ResponseStatus,例如:

http://jackson.codehaus.org/javadoc/jax-rs/1.0/javax/ws/rs/core/Response.ResponseBuilder.html#status%28javax.ws.rs.core.Response.Status%29

请记住,JSON信息更多的是与资源/应用程序关联的数据。HTTP代码更多的是关于被请求的CRUD操作的状态。(至少在REST-ful系统中是这样的)

我没有使用JAX-RS,但我有一个类似的场景,我使用:

response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());