Java 无法在ContainerRequestFilter中接收标头参数
我正在使用Jersey2.0用Java创建web服务。当我执行来自邮递员的请求时,一切正常,但当我执行来自客户端应用程序的请求时,我无法接收头参数。我的客户端应用程序是基于JavaScript的。此外,我还在ContainerResponseContext中添加了CORS允许原始请求参数 下面显示了我添加COR的ContainerResponseFilter类Java 无法在ContainerRequestFilter中接收标头参数,java,web-services,jersey-2.0,Java,Web Services,Jersey 2.0,我正在使用Jersey2.0用Java创建web服务。当我执行来自邮递员的请求时,一切正常,但当我执行来自客户端应用程序的请求时,我无法接收头参数。我的客户端应用程序是基于JavaScript的。此外,我还在ContainerResponseContext中添加了CORS允许原始请求参数 下面显示了我添加COR的ContainerResponseFilter类 @Provider class CORSFilter : ContainerResponseFilter { override
@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是请求的标题名。下面是我的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”头,这是日志
{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);
}
});
Edit2
我正在使用ResourceConfig来注册我的提供者。这是我的ResourceConfig类
class MyResourceConfig : ResourceConfig() {
init {
register(CORSFilter())
register(JsTokenFilterNeeded())
}
}
在真正的请求之前发生了一个错误。飞行前请求不发送任何标头(包括密钥标头)。它只发送头,询问服务器是否允许该请求。因此,当飞行前请求到达过滤器时,令牌将不在那里
您应该做的是使CorsFilter实现ContainerRequestFilter
和ContainerResponseFilter
。将其设置为@预匹配
过滤器。这样,它将在令牌筛选器之前被调用。在请求筛选器中,检查是否为飞行前请求。如果是,则中止请求。这将导致请求跳过其余的请求筛选器,直接转到响应筛选器。在响应过滤器端,您可以添加CORS头
您应该阅读本文,以更好地了解CORS协议的流程,并了解适用于您的场景的CorsFilter的更好实现。如您所述,从postman开始,一切正常。请在JS中共享客户端代码。此外,我建议打印整个日志(或调试)请求,并查看缺少的内容。我已经在问题末尾打印了日志。如果您看到Js代码,我将编辑我的问题。@AdiOhana添加了JavaScript代码。签出。您是否使用包扫描来发现提供者和资源?如果不是,则应显式注册CORSFilter@AdiOhana在发布我的问题之前,我已经看到了这个链接,而且我正在使用资源配置来注册我的提供者。