Jersey JAX-RS自定义异常Apper未截获运行时异常
我想将底层Jersey JAX-RS自定义异常Apper未截获运行时异常,jersey,jax-rs,Jersey,Jax Rs,我想将底层RuntimeExceptions包装为自定义json格式,使servlet容器不会将stacktrace转储到客户端 我遵循这个问题:。 打电话时: try { doSomething(parameters); } catch(RuntimeException e) { throw new MyCustomException(500 , e.getMessage() , Status.INTERNAL_SERVER_ERROR); } 当我故意输入错误的参数(并触发doSo
RuntimeExceptions
包装为自定义json格式,使servlet容器不会将stacktrace转储到客户端
我遵循这个问题:。
打电话时:
try {
doSomething(parameters);
}
catch(RuntimeException e) {
throw new MyCustomException(500 , e.getMessage() , Status.INTERNAL_SERVER_ERROR);
}
当我故意输入错误的参数(并触发doSomething()
引发的RuntimeException
)时,我没有看到MyCustomExceptionMapper
起作用。相反,servlet容器转储:
The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
api.MyCustomException: (underlaying msgs)
MyCustomExceptionMapper
确实已在javax.ws.rs.core.Application
中注册:
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(other classes);
set.add(MyCustomExceptionMapper.class);
return set;
}
事实上,它从未展示过
我确信此ApiConfig位于web.xml中:
<context-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>destiny.web.api.ApiConfig</param-value>
</context-param>
javax.ws.rs.core.Application
destiny.web.api.ApiConfig
但是为什么Jersey似乎从不调用它呢?我认为(根据我的实验),异常提供程序是通过精确的类匹配而不是继承匹配来查找的,因此处理RuntimeException
的异常提供程序只有在应用程序抛出原始RuntimeException
时才会启动;你给我们看的课不是这样的。我有一些关于如何解决这个问题的理论(例如,使用自定义过滤器处理程序,或者可能使用AOP),但还没有定论
关于你问题的后半部分,我只是不知道。我所知道的是,ApacheCXF(我使用过的JAX-RS实现)在这方面有一些缺陷,因此我坚持手工在应用程序的Spring配置中注册我所有的@Provider
。我提供的经验…我找到了解决方案
我所要做的就是用Spring的@存储库
注释MyCustomExceptionMapper
并删除web.xml中的部分(不需要)
javax.ws.rs.core.Application
destiny.web.api.ApiConfig
因为Spring将查找所有@Repository并找到@Provider,Jersey将使用它。您只需要在web.xml中配置servlet。您不需要将@Repository添加到ExceptionMapper
<servlet>
<servlet-name>rest-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>your.base.package.to.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
通过以下方式进行测试:
- 泽西岛v1.11 2011年9月12日上午10:27
- Spring v3.1.1
- GlassFish服务器开源版本3.1.2(构建23)
docs.oracle.com/cd/E24329_01/web.1211/e24983/configure.htm#RESTF179我遇到了同样的问题,web.xml中的更改,特别是在tag中的更改解决了这个问题。 只需确保的包含异常和异常映射器类的包,而不仅仅是包含模型和资源的包 jersey.config.server.provider.packages 基本包
例如,如果模型/实体的包为pkg.entity,异常为pkg.exception,则参数值(basepackage)将为pkg。如果将basepackage设置为pkg.entity,则它不起作用…这就是我解决问题的方法。“当选择异常映射提供程序来映射异常时,实现必须使用其泛型类型为最接近异常超类的提供程序。”@James您会认为这些事情总是正确实现的,不是吗?我也会这样做,除非经验告诉我不是这样(我想我正在考虑的实现非常喜欢使用
HashMap
s进行处理)。你唯一可以信赖的就是精确匹配。我同意软件总是有缺陷的。我们应该知道一旦遇到bug报告,如何创建bug报告。我正在当前项目中使用此功能。直到现在,一切都很顺利。为什么是@Repository?我想你的意思是应该用@Component注释它(就像所有其他资源一样)。我必须用javax.ws.rs.ext.Provider
注释我的。使用jersey 1.x
<context-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>destiny.web.api.ApiConfig</param-value>
</context-param>
<context-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>destiny.web.api.ApiConfig</param-value>
</context-param>
<servlet>
<servlet-name>rest-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>your.base.package.to.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
INFO: Scanning for root resource and provider classes in the packages:
your.base.package.to.rest
INFO: Root resource classes found:
class your.base.package.to.rest.resources.FooResource
INFO: Provider classes found:
class your.base.package.to.rest.providers.NotFoundMapper