我有一个泽西(2.14)应用程序,它可以正常工作。我在那里运行一些服务。现在我想配置ServletContainer,以便在任何地方截获并记录或通过电子邮件发送任何未捕获的异常。
我已经有了ApplicationEventListener的实现和用于生成异常的测试端点。
这是方法,它应该生成一个异常(这是工作:-):
@GET
@Path(TEST_EXCEPTION)
public String testException(@Context final ServletContext context) {
String s = null;
int size = 0;
if (System.nanoTime() % 10 != 0) {
s = null;
} else {
s = "No exception will occur";
}
size = s.length();
return Integer.toString(size) + ":" + s;
}
这是我的ApplicationEventListener:
的实现public class MyApplicationEventListener implements ApplicationEventListener {
private transient volatile int count = 0;
private int exceptions = 0;
@Override
public void onEvent(final ApplicationEvent applicationEvent) {
ApplicationEvent.Type type = applicationEvent.getType();
}
@Override
public RequestEventListener onRequest(final RequestEvent requestEvent) {
RequestEvent.Type type = requestEvent.getType();
if (type == RequestEvent.Type.ON_EXCEPTION) {
exceptions++;
}
count++;
return null;
}
}
这是我的web.xml中的配置:
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com....rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com....filter.MyApplicationEventListener
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.tracing</param-name>
<param-value>ALL</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
onEvent()和onRequest()都被调用,但是当发生异常时,我没有得到ON_EXCEPTION,而是一个START。
我做错了什么?或者我怎样才能获得Jersey服务方法产生的所有异常?
我想要/做一些像Spring的HandlerExceptionResolver。
答案 0 :(得分:3)
使用ExceptionMapper可以很容易地做到这一点。如果发生异常,您仍应将响应发送回客户端。但在这里你也可以发送电子邮件或记录票证等。
这是我为ConstraintViolations做的一个例子,但这可以是Exception类型的异常映射器。您可以检查异常的类型并执行相应的操作。在toResponse中,您可以实现一个notfiyEmail方法,该方法可以将堆栈跟踪和消息发送到电子邮件地址,例如,或者记录我过去做过的jira票证。请注意,您需要在顶部添加@Provider并告诉其余的Application / ResourceConfig扫描此类的包。或者,您可以使用ResourceConfig手动注册它。
@Provider
public class ConstraintViolationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
private static final Logger logger = Logger.getLogger(ConstraintViolationExceptionMapper.class.getName());
public Response toResponse(ConstraintViolationException exception) {
final int violationCount = exception.getConstraintViolations().size();
ConstraintViolation<?>[] constraintViolations = exception.getConstraintViolations().toArray(
new ConstraintViolation<?>[violationCount]);
Violation[] violations = new Violation[exception.getConstraintViolations().size()];
for (int i = 0; i < violationCount; i++) {
ConstraintViolation<?> cv = constraintViolations[i];
Violation violation = new Violation(cv.getPropertyPath().toString(), cv.getMessage());
violations[i] = violation;
}
ConstraintErrorResponse responseEntity = new ConstraintErrorResponse();
responseEntity.setViolations(violations);
logger.info("Seinding exception response");
return Response.status(Response.Status.BAD_REQUEST).entity(responseEntity).build();
}
}
答案 1 :(得分:0)
...当异常发生时,我没有得到ON_EXCEPTION,但是a START。
我做错了什么?
您需要从START事件返回RequestEventListener的实例,而不是返回null,以告诉Jersey为请求继续触发事件。
每次a时,Jersey运行时都会调用第二个onRequest方法 收到新请求。传递给方法的请求事件类型 总是开始。如果您想要监听任何其他请求生命周期 对于新请求的事件,您应该返回一个实例 RequestEventListener将处理请求。
有关记录异常事件的示例,请参阅https://stackoverflow.com/a/33271754/5473824。