java - 无法在 ContainerRequestFilter 中接收 header 参数

标签 java web-services jersey-2.0

我正在使用 Jersey2.0 在 Java 中创建 Web 服务。当我执行来自 POSTMAN 的请求时,一切都按预期工作,但是当我执行来自客户端应用程序的请求时,我无法接收 header 参数。我的客户端应用程序是基于 JavaScript 的。此外,我还在 ContainerResponseContext 中添加了 CORS 允许源请求参数。

下面显示了我添加 CORS 的 ContainerResponseFilter 类。

@Provider
class CORSFilter : ContainerResponseFilter {

    override fun filter(requestContext: ContainerRequestContext?, responseContext: ContainerResponseContext?) {
        responseContext?.apply {
            headers.add("Access-Control-Allow-Origin", "*")
            headers.add("Access-Control-Allow-Headers", "origin, content-type, authorization, accept, privatekey")
            headers.add("Access-Control-Allow-Credentials", "true")
            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
        }
    }
}

privatekey 是我的请求 header 名称。现在这是我的 ContainerRequestFilter 代码。

@Priority(AUTHENTICATION)
@Provider
class JsTokenFilterNeeded : JsBaseFilter(this::class.java.simpleName) {

    override fun filter(request: ContainerRequestContext?) {
        val path = request?.uriInfo?.path       
        val privateKeyHeaderValue = request?.getHeaderString("privatekey")
        println("private key -> $privateKeyHeaderValue")
    }
}

我总是在 privateKeyHeaderValue 中得到空值。两个容器都已在 ResourceConfig 类中成功注册。

截至目前,我在请求的资源上没有出现“Access-Control-Allow-Origin” header ,这是日志。

{host=[203.***.51.***:5555], connection=[keep-alive], access-control-request-method=[GET], origin=[http://localhost:38596], user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36], access-control-request-headers=[privatekey], accept=[*/*], alexatoolbar-alx_ns_ph=[AlexaToolbar/alx-4.0.3], referer=[http://localhost:38596/], accept-encoding=[gzip, deflate], accept-language=[en-US,en;q=0.9]}

编辑 1 这是我的客户端应用程序的 Js 代码。

$.ajax(
    {
        type: "GET",
        headers: {
            'privatekey': privateKey
        },
        url: "http://***.124.**.76:5555/dcu/energy/"+active_import,
        data: {
            'dcu_id': '99220445',
            'tariff': 0
        },
        error: function (result) {
            console.log(result);
        },
        success: function (result) {
            console.log(result);
        }
    });

编辑2 我正在使用 ResourceConfig 来注册我的提供商。这是我的 ResourceConfig 类。

class MyResourceConfig : ResourceConfig() {

    init {
        register(CORSFilter())
        register(JsTokenFilterNeeded())
    }
}

最佳答案

有一个preflight request那发生在真正的请求之前。预检请求不发送任何 header (包括 key header )。它只发送 header 询问服务器是否允许请求。因此,当预检请求到达过滤器时, token 将不存在。

您应该做的是让 CorsFilter 实现 ContainerRequestFilter ContainerResponseFilter。使它成为一个 @PreMatching 过滤器。这样它将在 token 过滤器之前被调用。在请求 过滤器中,检查它是否是预检请求。如果是,则中止请求。这将导致请求跳​​过其余的请求过滤器并直接进入响应 过滤器。在响应过滤器端,您可以添加 CORS header 。

你应该阅读 the UPDATE在这篇文章中,可以更好地了解 CORS 协议(protocol)的流程,并了解您可以使用的 CorsFilter 的更好实现,它应该适用于您的场景。

关于java - 无法在 ContainerRequestFilter 中接收 header 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55772933/

相关文章:

java - 从 XML Android Studio 导入 ID 开关

java - 使用 javassist 更改类(java 反射)

java - 当部署在 Glassfish 中时,基于 Spring-WS 的 SOAP 服务返回 405

c# - 我怎样才能将 web api 用作 web 服务?

java - 用于创建 JAX-WS 网络服务的简单 Maven 设置

servlets - Servlet 过滤器和 Jersey 过滤器有什么区别?

java - 数据绑定(bind)后组合框不可编辑

java - firebase数据库读取问题

java - 从 Jersey Rest 服务启动时,PhantomJS 返回黑色屏幕截图

java - 通过代理执行 POST 时,Jersey 客户端抛出 "Cannot retry request with a non-repeatable request entity."