4

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

web.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.

我如何告诉 JerseyDefaultExceptionMapper在 a 的情况下使用 my ConstraintViolationException

PS:我已经尝试过这里建议的选项:如果收到无效的 JSon而没有运气,则不会调用 ExceptionMapper。

4

2 回答 2

4

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

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

于 2015-12-24T13:16:26.037 回答
0

现在有一个简单的解决方法,完全禁用 Jersey 的 bean 验证。这可以通过让您的应用程序子类返回一个将ServerProperties.BV_FEATURE_DISABLE设置为 true 的属性来完成。

例如:

@ApplicationPath("")
public class MyApplication extends Application {

    @Override
    public Map<String, Object> getProperties() {
        return Collections.singletonMap(ServerProperties.BV_FEATURE_DISABLE, true);
    }
}
于 2017-02-09T13:25:48.567 回答