一尘不染

Java JAX-RS / Jersey如何自定义错误处理?

java

我正在使用Jersey来学习JAX-RS(又名JSR-311)。我已经成功创建了一个根资源,并且正在使用参数:

@Path("/hello")
public class HelloWorldResource {

    @GET
    @Produces("text/html")
    public String get(
        @QueryParam("name") String name,
        @QueryParam("birthDate") Date birthDate) {

         // Return a greeting with the name and age
    }
}

这很好用,并且可以处理Date(String)构造函数可以理解的当前语言环境中的任何格式(例如YYYY / mm / dd和mm / dd / YYYY)。但是,如果提供的值无效或无法理解,则会收到404响应。

例如:

GET /hello?name=Mark&birthDate=X

404 Not Found

如何自定义此行为?也许是不同的响应代码(可能是“ 400 Bad Request”)?记录错误该怎么办?也许在自定义标题中添加问题描述(“错误日期格式”)以帮助进行故障排除?还是返回带有详细信息的完整错误响应以及5xx状态代码?


阅读 284

收藏
2020-03-12

共1个答案

一尘不染

有几种方法可以自定义JAX-RS的错误处理行为。这是三种更简单的方法。

第一种方法是创建一个扩展WebApplicationExceptionException类。

例:

public class NotAuthorizedException extends WebApplicationException {
     public NotAuthorizedException(String message) {
         super(Response.status(Response.Status.UNAUTHORIZED)
             .entity(message).type(MediaType.TEXT_PLAIN).build());
     }
}

并抛出此新创建的异常,你只需:

@Path("accounts/{accountId}/")
    public Item getItem(@PathParam("accountId") String accountId) {
       // An unauthorized user tries to enter
       throw new NotAuthorizedException("You Don't Have Permission");
}

注意,你不需要在throws子句中声明异常,因为WebApplicationException是运行时异常。这将向客户端返回401响应。

第二种更简单的方法是WebApplicationException直接在代码中直接构造实例 。只要你不必实现自己的应用程序异常,这种方法就行。

例:

@Path("accounts/{accountId}/")
public Item getItem(@PathParam("accountId") String accountId) {
   // An unauthorized user tries to enter
   throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}

此代码也向客户端返回401。

当然,这只是一个简单的例子。如果需要,可以使Exception更为复杂,并且可以生成所需的http响应代码。

另一种方法是包装现有的Exception,可能是ObjectNotFoundException使用小型包装器类来包装,该类实现ExceptionMapper带有@Provider注释的接口。这告诉JAX-RS运行时,如果引发了包装的Exception,则返回中定义的响应代码ExceptionMapper

2020-03-12