java - JAXRS/Jersey 2 - 验证错误不调用 ExceptionMapper

标签 java jax-rs bean-validation exceptionmapper

使用最新的 Jersey (2.22.1),我已经成功地创建了我的自定义 validator 来满足各种需求。但是我的习惯ExceptionMapper (在 web.xml 中注册为 provider)在发生 ConstraintViolationException 时不会被调用,尽管它被定义为 ExceptionMapper<Throwable>。 .

网络.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="mywebapp" version="2.5">

    <display-name>Some Name - Webapp</display-name>

    [...]    

    <servlet>
        <servlet-name>jersey_v2-servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>
                com.myfirm.web.rest.providers.DefaultExceptionMapper,
                com.myfirm.web.rest.endpoints.XxxEndpoint,
                com.myfirm.web.rest.endpoints.XxyEndpoint,
                com.myfirm.web.rest.endpoints.XyzEndpoint
            </param-value>
        </init-param>

        <init-param>
            <param-name>jersey.config.beanValidation.enableOutputValidationErrorEntity.server</param-name>
            <param-value>true</param-value>
        </init-param>

        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey_v2-servlet</servlet-name>
        <url-pattern>/rest/1.0/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>jersey_v2-servlet</servlet-name>
        <url-pattern>/rest/latest/*</url-pattern>
    </servlet-mapping>

    [...]

</web-app>

默认异常映射器

@Provider
public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
    private static final Logger LOG = LoggerFactory.getLogger(DefaultExceptionMapper.class);

    @Override
    public Response toResponse(Throwable caughtException) {
        LOG.warn("Exception caught in the REST layer", caughtException);

        Throwable original = caughtException;

        // some business logic to convert the exception to a response

        // log & return the response
        Response response = status(status).entity(entity).build();
        return response;
    }

    @XmlRootElement
    public static class Error {
        @XmlElement
        public String type;

        @XmlElement
        public String message;

        @XmlElement
        public String translationKey;
    }
}

使用我的调试器,我可以在 org.glassfish.jersey.server.ServerRuntime 类的第 596 行中看到解析的映射器不是我的,而是一个 org.glassfish.jersey.server.validation.internal.ValidationExceptionMapper。 .

我如何告诉 Jersey 使用我的 DefaultExceptionMapperConstraintViolationException 的情况下?

PS:我已经尝试过这里建议的选项:ExceptionMapper not invoked if receiving invalid JSon没有运气。

最佳答案

将映射器定义为 implements ExceptionMapper<ConstraintViolationException>使它以某种方式优先于为相同异常类型注册的其他映射器。

我最终得到了 2 个异常映射器,一个用于每个异常,另一个用于 ConstraintViolationException , 都扩展了相同的抽象类。

关于java - JAXRS/Jersey 2 - 验证错误不调用 ExceptionMapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34452996/

相关文章:

java - 未在对象图上调用 Hibernate validator

java - 由 View 扩展的自定义 View 类的属性不起作用

java - 我是否需要在同一实例上的 Web 应用程序和 Web 服务内进行 HTTPS 通信?

java - 使用 Jackson 时忽略属性和访问器

Java Jersey PathParams 检查和 NotFoundException 自定义消息

java - 如何在表单对象上重新运行 Bean 验证? (Spring 4 MVC Controller )

Java泛型多次持有相同类型的参数

java - Jetty 9.4 在启动时启动两个 jvm

java - 首先是 InjectableProvider 还是 ExceptionMapper?

java - 我想有条件地验证一个对象