当前位置: 首页 > 知识库问答 >
问题:

Jersey:是否可以重写Jersey filter()的返回类型?

慎兴业
2023-03-14
Response response = Response.status(status).entity(errorMsg).build();
requestContext.abortWith(response);
@Path("/path")
@GET
public ReturnType endpoint(@Context ContainerRequestContext requestContext,
                           @CookieParam("cookieId") String cookieValue,
                           @HeaderParam("headerId") String headerValue, etc..){
    //do stuff
}

问题是,如果我执行上述^,以访问endpoint上的请求信息,则如果筛选器验证失败,我就不能再中止筛选器中的请求,因为我会得到以下错误:

java.lang.IllegalStateException: The request cannot be aborted as it is
already in the response processing phase.

似乎如果您在Jerseyendpoint上定义任何类型的参数,这些参数可以在ContainerRequestContext中访问,那么它将不允许您中止过滤器中的过滤器链。

一个解决方法(我还没有尝试过,但假设会成功)是这样做:如果过滤器验证失败,我可以只向请求添加一个自定义头,而不是试图在过滤器中中止请求。然后,在endpoint本身上,我可以进行检查,看看是否设置了该头。如果设置了它,我就知道过滤器验证失败了,然后我可以构建response对象并返回它。如果没有设置,我就知道筛选器验证成功了,我可以继续处理请求。

有人有办法解决我的困境吗?

共有1个答案

司空鸿禧
2023-03-14

找出问题的根源。我的筛选器是一个响应筛选器,如下所示:

class ResponseFilter implements ContainerResponseFilter{
    public void filter(ContainerRequestContext requestContext,
                       ContainerResponseContext responseContext){
        MultivaluedMap<String, Object> headers = responseContext.getHeaders();
        headers.add("Access-Control-Allow-Origin", "http://localhost:9000");
        headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        headers.add("Access-Control-Allow-Headers", "Content-Type" );
        headers.add("Access-Control-Allow-Credentials", "true" );
        if(requestValidationFailed){
            Response response = Response.status(status).entity(error).build();
            requestContext.abortWith(response);
        }
    }
}

从上面的代码示例中可以看到,在进行请求验证检查之前,我已经定义了响应头。通过这样做,Jersey假设我现在处于“响应处理阶段”。当我已经为响应设置头部时,它不会让我中止请求,这是有道理的。

可能有其他方法来解决这个问题,但是我通过将我的过滤器拆分为两个过滤器(两个独立的类)来解决这个问题。

class RequestFilter implements ContainerRequestFilter{
    public void filter(ContainerRequestContext requestContext){
        if(requestValidationFailed){
            Response response = Response.status(status).entity(error).build();
            requestContext.abortWith(response);
        }
}

class ResponseFilter implements ContainerResponseFilter{
    public void filter(ContainerRequestContext requestContext,
                       ContainerResponseContext responseContext){
        MultivaluedMap<String, Object> headers = responseContext.getHeaders();
        headers.add("Access-Control-Allow-Origin", "http://localhost:9000");
        headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        headers.add("Access-Control-Allow-Headers", "Content-Type" );
        headers.add("Access-Control-Allow-Credentials", "true" );
    }
}
 类似资料:
  • 就说,我问题的重点是学会理解jls。我相信jls中的一切都是真的。 考虑JLS下一个片段: 8.4.8.1。重写(通过实例方法) 在类C中声明的实例方法m1重写在类A中声明的另一个实例方法m2,前提是以下所有条件均为真: C是a的一个子类。 m1的签名是m2签名的子签名(§8.4.2)。 要么: m2是公共的、受保护的或在与C相同的包中声明具有默认访问权限的,或者 m1覆盖方法m3(m3不同于m1

  • 问题内容: 重写的方法可以有不同的返回类型吗? 问题答案: Java支持*协变返回类型的重写方法。这意味着重写的方法可能具有更特定的返回类型。也就是说,只要新的返回类型可分配给你要覆盖的方法的返回类型,就可以使用。 例如: 这在Java语言规范的8.4.5节中指定: 如果返回类型是引用类型,则返回类型在彼此覆盖的方法之间可能会有所不同。返回类型可替换性的概念支持协变返回,即返回类型到子类型的特殊化

  • 重写的方法可以有不同的返回类型吗?

  • 给定一个具有用于初始化的帮助器方法的类: 是否可以从\u int方法注释

  • 问题内容: 如果实际查询不返回任何行,是否可以将查询中的所有列作为空列(不为null)或空行返回 问题答案: 通常,如果必须返回一个空行。 如果您的原始查询是 您可以将其变成子查询 这样可以确保查询的行数始终至少为1。