由于服务器是高度敏感的,因此jax-ws将Content-type更改为Content-Type [英] jax-ws change Content-type to Content-Type because server is hyper sensitive
问题描述
我必须连接到只能理解 Content-Type
(capital-T)而不是 Content-type
。我怎么才能让我的JAX-WS客户端发送 Content-Type
?
我试过了:
映射< String,List< String>>头文件=(Map< String,List< String>>)
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
但是标头
是空
。我做错了什么?
我必须连接到只能理解的服务器内容类型(资本-T)而不是内容类型。我怎么才能让我的jax-ws客户端发送Content-Type?
我已经挖掘了这个问题, ,恐怕答案是:你不能。让我分享我的发现。
首先,您可以在 https://jax-ws.dev.java.net/guide/HTTP_headers.html 不允许访问未来HTTP请求的HTTP标头(此时尚未创建),它允许您为发出请求设置附加HTTP标头(稍后将添加到HTTP请求中)。
所以,不要指望下面的代码不会返回 null
,如果你没有放入
之前的任何东西(实际上,你只会得到你放入
那里):
((BindingProvider)port).getRequestContext()。get(MessageContext.HTTP_REQUEST_HEADERS);
然后,我根据同一链接中提供的代码做了一些测试:
AddNumbersImplService service = new AddNumbersImplService();
AddNumbersImpl port = service.getAddNumbersImplPort();
((BindingProvider)port).getRequestContext()。put(MessageContext.HTTP_REQUEST_HEADERS,
Collections.singletonMap(X-Client-Version,Collections.singletonList(1.0-RC )));
port.addNumbers(3,5);
这就是我在运行客户端代码时在HTTP请求中看到的内容:
POST / q2372336 / addnumbers HTTP / 1.1
Content-type:text / xml; charset =utf-8
X-客户端版本:1.0-RC
Soapaction:
接受:text / xml,multipart / related,text / html,image / gif,image / jpeg,*; q = .2,* / *; q = .2
用户代理:JDK 6中的JAX-WS RI 2.1.6
主机:localhost:8080
连接:keep-alive
Content-Length:249
您是否注意到不同之处:只有 X-Client-Version
标题保持上层,其余的降低!
事实上,如果您检查课程 csxwtHeaders
,您将看到它在添加它们时标准化了密钥(在 normalize(String)
):
/ *通过转换为以下形式。
*首字符大写,小写其余。
* key假定为ASCII
* /
private String normalize(String key){
...
}
所以,当 csxwthcHttpTransportPipe
class(我的理解是这是创建HTTP请求的地方,这也是以前添加的头文件将被添加到HTTP请求头文件中的地方)实际上添加了 Content-Type
作为 csxwtHeaders
实例,因为前面提到的实现细节,密钥会被修改。
我可能是错的,但我不明白如何在没有pa修改代码。而奇怪的是,我不认为这个正常化的东西真的是符合RFC的(虽然没有检查RFC对于标题情况的说法)。我很惊讶。实际上,您应该提出问题。
所以我在这里看到三个选项(因为等待修复可能不是一个选项):
I have to connect to a poorly implemented server that only understands Content-Type
(capital-T) and not Content-type
. How can I ask my JAX-WS client to send Content-Type
?
I've tried:
Map<String, List<String>> headers = (Map<String, List<String>>)
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
But headers
is null
. What am I doing wrong?
I have to connect to a poorly implemented server that only understands Content-Type(capital-T) and not Content-type. How can I ask my jax-ws client to send Content-Type?
I've dug this question a bit more and, sadly, I'm afraid the answer is: you can't. Let me share my findings.
First, the code that you'll find in https://jax-ws.dev.java.net/guide/HTTP_headers.html does not give you access to the HTTP headers of the future HTTP request (that hasn't been created at this point), it allows you to set additional HTTP headers for making a request (that will be added to the HTTP request later).
So, don't expect the following code to not return null
if you don't put
anything before (and actually, you'll only get what you put
in there):
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Then, I did a little test based on the code provided in the same link:
AddNumbersImplService service = new AddNumbersImplService();
AddNumbersImpl port = service.getAddNumbersImplPort();
((BindingProvider)port).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
Collections.singletonMap("X-Client-Version",Collections.singletonList("1.0-RC")));
port.addNumbers(3, 5);
And this is what I see in the HTTP request when running the client code:
POST /q2372336/addnumbers HTTP/1.1 Content-type: text/xml;charset="utf-8" X-client-version: 1.0-RC Soapaction: "" Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 User-Agent: JAX-WS RI 2.1.6 in JDK 6 Host: localhost:8080 Connection: keep-alive Content-Length: 249
Do you notice the difference: only the first char of the X-Client-Version
header is kept upper cased, the rest is lowered!
And indeed, if you check the class c.s.x.w.t.Headers
that is used to represent HTTP request (and response) headers, you'll see that it "normalizes" keys when they are added (in normalize(String)
):
/* Normalize the key by converting to following form.
* First char upper case, rest lower case.
* key is presumed to be ASCII
*/
private String normalize (String key) {
...
}
So, while the c.s.x.w.t.h.c.HttpTransportPipe
class (my understanding is that this is where the HTTP request is created, this is also where previously added headers will be added to the HTTP request headers) actually adds "Content-Type"
as key in a c.s.x.w.t.Headers
instance, the key will be modified because of the previously mentioned implementation detail.
I may be wrong but I don't see how this could be changed without patching the code. And the odd part is that I don't think that this "normalizing" stuff is really RFCs compliant (didn't check what RFCs say about headers case though). I'm surprised. Actually, you should raise an issue.
So I see three options here (since waiting for a fix might not be an option):
- Patch the code yourself and rebuild JAX-WS RI (with all the drawbacks of this approach).
- Try another JAX-WS implementation like CFX for your client.
- Let the request go through some kind of custom proxy to modify the header on the fly.
这篇关于由于服务器是高度敏感的,因此jax-ws将Content-type更改为Content-Type的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!