我已经实现了一个自定义异常映射器,以便在我的应用程序中抛出错误的请求。这是代码:
CustomFilterBadRequest:
package com.test.exceptions;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import java.util.Date;
public class CustomFilterBadRequest extends Exception implements
ExceptionMapper<CustomFilterBadRequest> {
private String uriInfo;
public CustomFilterBadRequest() {
super("Invalid Request. Please try again with the valid request");
}
public CustomFilterBadRequest(String uriInfo, String message) {
super(message);
this.uriInfo = uriInfo;
}
@Override
public Response toResponse(CustomFilterBadRequest exception) {
return Response.status(400).entity(new ErrorDetails(new Date(),
400, "bad request", exception.getMessage(),this.uriInfo)).type(MediaType.APPLICATION_JSON).build();
}
}
问题:
注意: 在这个例子中,我有一个名为uriInfo的实例变量。 从另一项服务,我做:
throw new CustomFilterBadRequest("uri","message")
立即调用构造函数,并将我的uriInfo设置为值&#34; uri&#34;。在此之后,调用toResponse方法。我的uriInfo实例变量被重置。为什么?然而,当我将实例变量设为静态时,保留该值。
我无法获得有关此内容的任何文档。请帮忙。
***** UPDATE *****
当调用与此异常相关的REST端点时,将调用CustomFilterBadRequest的默认构造函数,创建状态为uriInfo的对象,将其初始化为null。让我们将此对象称为object1。
当我们抛出新的CustomFilterBadRequest(&#34; uri&#34;,&#34; msg&#34;)时,会创建一个对象,其状态为uriInfo,初始化为值uri。我们将此对象称为object2。
JAX-RS运行时将CustomFilterBadRequest异常映射到异常映射器,此处也是CustomFilterBadRequest。因此调用了响应方法。它从object1获取uriInfo。 (这里显然是空的)
并且我们不必在Custom异常映射器中仅使用类变量。
这种实现非常混乱。我已经在下面的答案中更新了直接的实现。
答案 0 :(得分:0)
问题是在JAX-RS运行时注册的toResponse(...)
实例上调用CustomFilterBadRequest
方法。如果在注册中使用no-arg构造函数,那么uriInfo总是将其默认值设置为null。
我建议您在一个类中定义异常,并在另一个类中定义异常处理程序。
例外:
public class CustomBadRequest extends Exception {
private String uriInfo;
public CustomBadRequest() {
super("Invalid Request. Please try again with the valid request");
}
public CustomBadRequest(String uriInfo, String message) {
super(message);
this.uriInfo = uriInfo;
}
public String getUriInfo() {
return uriInfo;
}
}
ExceptionMapper:
@Provider
public class CustomFilterBadRequest implements ExceptionMapper<CustomBadRequest> {
@Override
public Response toResponse(CustomBadRequest exception) {
return Response.status(400).entity(new ErrorDetails(new Date(),
400, "bad request", exception.getMessage(),exception.getUriInfo())).type(MediaType.APPLICATION_JSON).build();
}
}
答案 1 :(得分:0)
我理解这个问题背后的原因。
每当我们到达终点时,都会调用在泽西注册的异常映射器的默认构造函数,并创建每种类型的对象,并将状态初始化为其类型的默认值。
抛出自定义异常时,将创建自定义异常对象,JAX-RS运行时搜索异常映射器以映射异常。如果未找到,则只映射到默认的异常映射器。如果找到自定义异常映射器,则调用toResponse方法。在这种情况下,我们应该在toResponse方法中从其对象本身获取customexception的状态。
我需要这个来获取exceptionmapper中的uriInfo。
这是工作代码:
CustomFilterBadRequest.java
public class CustomFilterBadRequest extends Exception {
public CustomFilterBadRequest(String message) {
super(message);
}
}
CustomFilterBadRequestExceptionMapper.java
public class CustomFilterBadRequestExceptionMapper implements ExceptionMapper<CustomFilterBadRequest> {
private UriInfo uriInfo;
public CustomFilterBadRequestExceptionMapper(@Context UriInfo uriInfo) {
this.uriInfo = uriInfo;
}
@Override
public Response toResponse(CustomFilterBadRequest exception) {
return Response.status(400).entity(new ErrorDetails(Instant.now(),
400, "bad request", exception.getMessage(),this.uriInfo.getPath())).type(MediaType.APPLICATION_JSON).build();
}
}
非常感谢大家的回应。
答案 2 :(得分:0)
我很确定这就是你要做的全部:
CustomFilterBadRequest:
package com.test.exceptions;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import java.util.Date;
public class CustomFilterBadRequest extends Exception implements
ExceptionMapper<CustomFilterBadRequest> {
private String uriInfo;
public CustomFilterBadRequest() {
super("Invalid Request. Please try again with the valid request");
}
public CustomFilterBadRequest(String uriInfo, String message) {
super(message);
this.uriInfo = uriInfo;
}
@Override
public Response toResponse(CustomFilterBadRequest exception) {
return Response.status(400).entity(new ErrorDetails(new Date(),
400, "bad request", exception.getMessage(),exception.uriInfo)).type(MediaType.APPLICATION_JSON).build();
}
}
我刚刚将this.uriInfo
更改为exception.uriInfo
基本上,当您抛出CustomFilterBadRequestException时,JAX-RS会创建一个新实例来映射您抛出的异常。此新实例的默认值为uriInfo。因此它没有被保存。
无论你做什么,都不要让uriInfo
静止。这会导致巨大的并发问题。