自定义jersey param抛出异常时的MultiException

Sri*_*nth 12 java jax-rs dropwizard jersey-2.0

注意:有关重现此问题的所有代码,请访问https://gist.github.com/SrikanthRao/c9fc35e6fe22a74ab40c

http:// localhost:8080/date/bean?date = 2014-13-23 (使用BeanParam)生成"{"代码":500,"message":"处理您的请求时出错.它已被记录(ID 48be9aa43bd49547)."}"而没有将MultiExceptionMapper添加到泽西.

如果我将MultiExceptionMapper添加到jersey,则上面的url会导致

"日期不是YYYY-MM-DD格式或无效"

http:// localhost:8080/date?date = 2014-13-23(直接@QueryParam参数)生成"日期不是YYYY-MM-DD格式或无效"

几个问题:

  1. 这是以更干净的方式处理输入验证的正确方法吗?
  2. 我希望这可以工作,而无需添加我自己的MultiExceptionMapper.Jersey是否支持在资源方法中作为@BeanParam注入的POJO中的自定义*Params?

这是请求时生成的堆栈跟踪(不将MultiExceptionMapper添加到jersey).当然删除了很长的痕迹.如果您需要完整的堆栈跟踪,请告诉我.

    ERROR [2015-05-04 18:48:33,366] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: 0f23e4de758653d6
    ! javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
    ! at io.dropwizard.jersey.params.AbstractParam.<init>(AbstractParam.java:28) ~[dropwizard-jersey-0.8.1.jar:0.8.1]
    ! at com.fun.myapp.LocalDateTimeParam.<init>(LocalDateTimeParam.java:20) ~[classes/:na]
    ! at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_45]
...
...
Causing: org.glassfish.hk2.api.MultiException: A MultiException has 3 exceptions.  They are:
! 1. javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
! 2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.fun.myapp.PaginationFilters errors were found
! 3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.fun.myapp.PaginationFilters
! 
! at org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:88) ~[hk2-locator-2.4.0-b10.jar:na]
! at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:252) ~[hk2-locator-2.4.0-b10.jar:na]
! at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360) ~[hk2-locator-2.4.0-b10.jar:na]
! at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471) ~[hk2-locator-2.4.0-b10.jar:na]
....
....
WARN  [2015-05-04 18:48:33,401] org.glassfish.jersey.internal.Errors: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
    at io.dropwizard.jersey.params.AbstractParam.<init>(AbstractParam.java:28)
    at com.fun.myapp.LocalDateTimeParam.<init>(LocalDateTimeParam.java:20)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
...
...
MultiException stack 2 of 3
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.fun.myapp.PaginationFilters errors were found
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:249)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
...
...
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: resolve on com.fun.myapp.PaginationFilters
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:389)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
Run Code Online (Sandbox Code Playgroud)

我在dropwizard-user google group上提出了这个问题 - https://groups.google.com/forum/#!topic/dropwizard-user/yW-RXSSlspY

Guy*_*let 4

问题1

根据 dropwizard 的核心文档,我看到输入验证有两种可能的实现:

  • 通过验证注解

您可以将验证注释添加到表示类的字段并验证它们...

这似乎不适合您的情况。事实上,LocalDateTime 没有可用的注释,创建注释会导致解析 LocalDateTime 两次:用于验证和设置 bean 字段。

  • 通过错误处理:

如果您想要更多控制,您还可以在环境中声明 JerseyProviders,通过使用 javax.ws.rs.ext.ExceptionMapper 的实现调用 JerseyEnvironment#register(Object) 来将异常映射到某些响应...

为了回答你的第一个问题,我想说,在你的情况下使用异常映射器是完全可以的。

问题 2 调试两个 isValidDate 方法表明 @BeanParam 版本使用 ClazzCreator.java,而 @QueryParam 则不使用。该类负责创建 bean 类实例。如果您检查该类的第 226 行,您会发现它在解析具有多个错误的输入时收集了多个异常。这应该允许报告与不同 bean 字段相关的多个错误,包括一些后续异常。

答案是 Jeysey 支持 POJO 内的 *Params。然而,相关的异常被封装成@BeanParam上下文中的MultiException。因此,如果您计划向 PaginationFilters 添加其他字段,则应考虑在映射的异常消息中报告多个错误。