无法在 ContainerRequestFilter 中接收 header 参数
Not able to receive header parameter in ContainerRequestFilter
我正在使用 Jersey2.0 在 Java 中创建 web-services。当我执行来自 POSTMAN 的请求时,一切都按预期工作,但是当我执行来自客户端应用程序的请求时,我无法接收 header 参数。我的客户端应用程序在 JavaScript 上。此外,我在 ContainerResponseContext 中添加了 CORS 允许源请求参数。
下面显示了我的 ContainerResponseFilter class 我在其中添加了 CORS。
@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")
}
}
}
私钥 是我的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 class.
中成功注册
截至目前,我在请求的资源上没有 '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.
class MyResourceConfig : ResourceConfig() {
init {
register(CORSFilter())
register(JsTokenFilterNeeded())
}
}
在实际请求之前发生了一个 preflight request。预检请求不发送任何 header(包括密钥 header)。它只发送 headers 询问服务器是否允许请求。所以当预检请求到达过滤器时,令牌不会在那里。
您应该做的是让 CorsFilter 实现 ContainerRequestFilter
和 ContainerResponseFilter
。将其设为 @PreMatching
过滤器。这样它将在令牌过滤器之前被调用。在 request 过滤器中,检查它是否是预检请求。如果是,则中止请求。这将导致请求跳过其余的请求过滤器并直接进入 response 过滤器。在响应过滤器端,您可以添加 CORS headers.
您应该阅读此 post 中的 the UPDATE 以更好地了解 CORS 协议的流程,并查看您可以使用的 CorsFilter 的更好实现,它应该适用于您的情景.
我正在使用 Jersey2.0 在 Java 中创建 web-services。当我执行来自 POSTMAN 的请求时,一切都按预期工作,但是当我执行来自客户端应用程序的请求时,我无法接收 header 参数。我的客户端应用程序在 JavaScript 上。此外,我在 ContainerResponseContext 中添加了 CORS 允许源请求参数。
下面显示了我的 ContainerResponseFilter class 我在其中添加了 CORS。
@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")
}
}
}
私钥 是我的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 class.
中成功注册截至目前,我在请求的资源上没有 '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.
class MyResourceConfig : ResourceConfig() {
init {
register(CORSFilter())
register(JsTokenFilterNeeded())
}
}
在实际请求之前发生了一个 preflight request。预检请求不发送任何 header(包括密钥 header)。它只发送 headers 询问服务器是否允许请求。所以当预检请求到达过滤器时,令牌不会在那里。
您应该做的是让 CorsFilter 实现 ContainerRequestFilter
和 ContainerResponseFilter
。将其设为 @PreMatching
过滤器。这样它将在令牌过滤器之前被调用。在 request 过滤器中,检查它是否是预检请求。如果是,则中止请求。这将导致请求跳过其余的请求过滤器并直接进入 response 过滤器。在响应过滤器端,您可以添加 CORS headers.
您应该阅读此 post 中的 the UPDATE 以更好地了解 CORS 协议的流程,并查看您可以使用的 CorsFilter 的更好实现,它应该适用于您的情景.