Wildfly:ExceptionMapper 未通过 RestEasy JSR-303 Bean 验证触发
Posted
技术标签:
【中文标题】Wildfly:ExceptionMapper 未通过 RestEasy JSR-303 Bean 验证触发【英文标题】:Wildfly: ExceptionMapper not triggered with RestEasy JSR-303 Bean Validation 【发布时间】:2015-12-19 22:23:56 【问题描述】:我在 Wildfly 8.2.0.Final 中使用带有 RestEasy 的 Bean 验证:
@Path("/user")
@Produces(MediaType.APPLICATION_JSON)
public class UserEndpoint
//more code
@GET
@Path("/encrypt/email")
public Response fetchEncryptedId(@PathParam("email") @NotNull String email)
String encryptedUserId = userService.getEncryptedUserId(email);
return Response.ok().entity(new UserBo(encryptedUserId)).build();
这基本上有效。现在我想以 JSON 对象的形式获取响应,但我无法让它工作。我所有的“应用程序”异常都由我的异常映射器处理,这很有效:
@Provider
public class DefaultExceptionMapper implements ExceptionMapper<Exception>
private static final String MEDIA_TYPE = "application/json";
private LoggingService loggingService;
@EJB
public void setLoggingService(LoggingService loggingService)
this.loggingService = loggingService;
@Override
public Response toResponse(Exception exception)
ResponseObject responseObject = new ResponseObject();
responseObject.registerExceptionMessage(exception.getMessage());
if (exception instanceof ForbiddenException)
loggingService.log(LogLevel.ERROR, ((ForbiddenException)exception).getUserId(), ExceptionToStringMapper.map(exception));
return Response.status(Status.FORBIDDEN).type(MEDIA_TYPE).entity(responseObject).build();
//more handling
loggingService.log(LogLevel.ERROR, "", ExceptionToStringMapper.map(exception));
return Response.status(Status.INTERNAL_SERVER_ERROR).type(MEDIA_TYPE).entity(responseObject).build();
但 bean 验证以某种方式绕过它。然后我考虑使用 Throwable 而不是 Exception 但它也没有帮助。我猜 ExceptionMapper 没有被触发,因为 JAX-RS 和 JSR303 存在一些生命周期问题。但是我怎样才能同步它们来处理 bean 验证异常呢?
附加信息:异常通过了javax.ws.rs.container.ContainerResponseFilter
,所以我可以通过在子类中实现过滤器方法来编写一些解决方法,但这不是干净的解决方案。目标是处理异常映射器中的异常。
【问题讨论】:
我认为异常映射器是要走的路。另见***.com/questions/10516516/…。不知道为什么这在这种情况下不起作用。您是否尝试过按照其他帖子的建议注册专用映射器? @Hardy 我也不是,这就是我问的原因。帖子中的映射器与我的相同,因此我的更宽容,因为我基本上捕捉到任何异常,而不仅仅是 ConstraintViolationException。 (我在调试器中,但它没有被调用) 【参考方案1】:您的ExceptionMapper<Exception>
并不总是会捕获Exception
层次结构下的所有异常。如果有另一个更具体的映射器,比如RuntimeException
,那个 映射器将用于RuntimeException
及其子类型的所有异常。
话虽如此(假设您使用的是resteasy-validation-provider-11
),已经有一个ResteasyViolationExceptionMapper
处理ValidationException
。
@Provider
public class ResteasyViolationExceptionMapper
implements ExceptionMapper<ValidationException>
这个映射器是自动注册的。它以ViolationReport
的形式返回结果。客户端需要将 Accept
标头设置为 application/json
才能看到类似于
"exception":null,
"fieldViolations":[],
"propertyViolations":[],
"classViolations":[],
"parameterViolations":[
"constraintType":"PARAMETER",
"path":"get.arg0",
"message":"size must be between 2 and 2147483647",
"value":"1"
],
"returnValueViolations":[]
你可以在Violation reporting看到更多。
如果你想完全覆盖这个行为,你可以为ResteasyViolationException
创建一个更具体的映射器,也就是RESTeasy验证器抛出的异常
@Provider
public class MyValidationMapper
implements ExceptionMapper<ResteasyViolationException>
@Override
public Response toResponse(ResteasyViolationException e)
【讨论】:
谢谢,两种解决方案都有效。当我可以奖励赏金时,我会接受它。以上是关于Wildfly:ExceptionMapper 未通过 RestEasy JSR-303 Bean 验证触发的主要内容,如果未能解决你的问题,请参考以下文章
Wildfly 10.1.0 - 未找到 Mysql 数据源