为什么 Custom Exception Mapper 中的实例变量必须是静态的?
Why instance variable inside Custom Exception Mapper has to be static?
我已经实现了一个自定义异常映射器,以便在我的应用程序中抛出错误的请求。这是代码:
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 设置为值 "uri"。此后,toResponse 方法获取 called.My uriInfo 实例变量被重置。为什么?然而,当我将实例变量设为静态时,该值将被保留。
我无法获得关于此的任何文档。请帮忙
*****更新*****
当调用与此异常相关的 REST 端点时,将调用 CustomFilterBadRequest 的默认构造函数,创建状态 uriInfo 初始化为 null 的对象。让我们称这个对象为 object1.
当我们抛出 new CustomFilterBadRequest("uri","msg") 时,会创建一个对象,其状态 uriInfo 初始化为值 uri。我们称这个对象为 object2.
JAX-RS 运行时将 CustomFilterBadRequest 异常映射到异常映射器,这里也是 CustomFilterBadRequest。因此 toResponse 方法被调用。它从 object1 获取 uriInfo。 (这里显然是空的)
我们没有必要在自定义异常映射器中只使用 class 个变量。
这种实现方式比较混乱。我在下面的答案中更新了直接实施。
问题是在 CustomFilterBadRequest
的实例上调用了 toResponse(...)
方法,该实例已注册到 JAX-RS 运行时。如果在注册中使用 no-arg 构造函数,这就是为什么 uriInfo 始终具有默认值 null 的原因。
我建议您在一个 class 中定义异常,在另一个中定义异常处理程序。
异常:
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;
}
}
异常映射器:
@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();
}
}
我了解问题背后的原因。
每当我们到达终点时,都会调用在球衣上注册的异常映射器的默认构造函数,并创建每种类型的对象,并将状态初始化为其类型的默认值。
当抛出自定义异常时,创建自定义异常对象并且JAX-RS运行时搜索异常映射器来映射异常。如果找到 none,它就映射到默认的异常映射器。如果找到自定义异常映射器,则调用 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();
}
}
非常感谢大家的回复。
我很确定这就是您要做的全部事情:
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
静止。那会导致巨大的并发问题。
我已经实现了一个自定义异常映射器,以便在我的应用程序中抛出错误的请求。这是代码:
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 设置为值 "uri"。此后,toResponse 方法获取 called.My uriInfo 实例变量被重置。为什么?然而,当我将实例变量设为静态时,该值将被保留。
我无法获得关于此的任何文档。请帮忙
*****更新*****
当调用与此异常相关的 REST 端点时,将调用 CustomFilterBadRequest 的默认构造函数,创建状态 uriInfo 初始化为 null 的对象。让我们称这个对象为 object1.
当我们抛出 new CustomFilterBadRequest("uri","msg") 时,会创建一个对象,其状态 uriInfo 初始化为值 uri。我们称这个对象为 object2.
JAX-RS 运行时将 CustomFilterBadRequest 异常映射到异常映射器,这里也是 CustomFilterBadRequest。因此 toResponse 方法被调用。它从 object1 获取 uriInfo。 (这里显然是空的)
我们没有必要在自定义异常映射器中只使用 class 个变量。
这种实现方式比较混乱。我在下面的答案中更新了直接实施。
问题是在 CustomFilterBadRequest
的实例上调用了 toResponse(...)
方法,该实例已注册到 JAX-RS 运行时。如果在注册中使用 no-arg 构造函数,这就是为什么 uriInfo 始终具有默认值 null 的原因。
我建议您在一个 class 中定义异常,在另一个中定义异常处理程序。
异常:
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;
}
}
异常映射器:
@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();
}
}
我了解问题背后的原因。
每当我们到达终点时,都会调用在球衣上注册的异常映射器的默认构造函数,并创建每种类型的对象,并将状态初始化为其类型的默认值。
当抛出自定义异常时,创建自定义异常对象并且JAX-RS运行时搜索异常映射器来映射异常。如果找到 none,它就映射到默认的异常映射器。如果找到自定义异常映射器,则调用 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();
}
}
非常感谢大家的回复。
我很确定这就是您要做的全部事情:
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
静止。那会导致巨大的并发问题。