Wildfly:ExceptionMapper不是通过RestEasy JSR-303 Bean验证触发的

Bev*_*vor 4 json resteasy bean-validation wildfly wildfly-8

我在Wildfly 8.2.0中使用Bean验证和RestEasy.最后:

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这基本上有效.现在我想把响应作为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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但bean验证以某种方式绕过它.然后我想到使用Throwable而不是Exception,但它也没有帮助.我猜不会触发ExceptionMapper,因为JAX-RS和JSR303存在一些生命周期问题.但是,我如何同步它们以处理bean验证异常?附加信息:异常通过,javax.ws.rs.container.ContainerResponseFilter所以我可以通过在子类中实现filter方法来编写一些解决方法,但这不是干净的解决方案.目标是处理异常映射器中的异常.

Pau*_*tha 7

并非总是ExceptionMapper<Exception>会在Exception层次结构下捕获所有异常.如果还有另一个更具体的映射器,例如一个映射器RuntimeException,则映射器将用于RuntimeException其子类型的所有异常.

话虽如此(假设你正在使用resteasy-validation-provider-11),已经有一个ResteasyViolationExceptionMapper处理ValidationException.

@Provider
public class ResteasyViolationExceptionMapper 
        implements ExceptionMapper<ValidationException>
Run Code Online (Sandbox Code Playgroud)

此映射器将自动注册.它以a的形式返回结果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":[]
}
Run Code Online (Sandbox Code Playgroud)

您可以在违规报告中查看更多内容.

如果要完全覆盖此行为,可以为其创建更具体的映射器ResteasyViolationException,这是RESTeasy验证器抛出的异常

@Provider
public class MyValidationMapper
        implements ExceptionMapper<ResteasyViolationException> {

    @Override
    public Response toResponse(ResteasyViolationException e) {

    }
}
Run Code Online (Sandbox Code Playgroud)