問(wèn)題描述
我必須連接到一個(gè)執(zhí)行不佳的服務(wù)器,該服務(wù)器只能理解 Content-Type
(capital-T) 而不是 Content-type
.如何讓我的 JAX-WS 客戶端發(fā)送 Content-Type
?
我試過(guò)了:
地圖<字符串,列表<字符串>>標(biāo)頭=(地圖<字符串,列表<字符串>>)((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
但是 headers
是 null
.我做錯(cuò)了什么?
我必須連接到一個(gè)執(zhí)行不佳的服務(wù)器,該服務(wù)器只理解 Content-Type(capital-T) 而不是 Content-type.如何讓我的 jax-ws 客戶端發(fā)送 Content-Type?
我對(duì)這個(gè)問(wèn)題進(jìn)行了更多研究,但遺憾的是,恐怕答案是:你不能.讓我分享一下我的發(fā)現(xiàn).
首先,您將在 https://jax- 中找到代碼ws.dev.java.net/guide/HTTP_headers.html 不允許您訪問(wèn)未來(lái) HTTP 請(qǐng)求的 HTTP 標(biāo)頭(此時(shí)尚未創(chuàng)建),它允許您設(shè)置用于發(fā)出請(qǐng)求的附加 HTTP 標(biāo)頭(稍后將添加到 HTTP 請(qǐng)求中).
所以,如果你之前沒(méi)有 put
任何東西,不要期望下面的代碼不會(huì)返回 null
(實(shí)際上,你只會(huì)得到你 <代碼>把放在那里):
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
然后,我根據(jù)同一個(gè)鏈接中提供的代碼做了一個(gè)小測(cè)試:
AddNumbersImplService 服務(wù) = new AddNumbersImplService();AddNumbersImpl 端口 = service.getAddNumbersImplPort();((BindingProvider)port).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,Collections.singletonMap("X-Client-Version",Collections.singletonList("1.0-RC")));port.addNumbers(3, 5);
這就是我在運(yùn)行客戶端代碼時(shí)在 HTTP 請(qǐng)求中看到的內(nèi)容:
<上一頁(yè)>發(fā)布/q2372336/addnumbers HTTP/1.1內(nèi)容類型:text/xml;charset="utf-8"X 客戶端版本:1.0-RC皂化:"接受:text/xml、multipart/related、text/html、image/gif、image/jpeg、*;q=.2, */*;q=.2用戶代理:JDK 6 中的 JAX-WS RI 2.1.6主機(jī):本地主機(jī):8080連接:保持活動(dòng)內(nèi)容長(zhǎng)度:249你注意到區(qū)別了嗎:只有 X-Client-Version
標(biāo)頭的第一個(gè)字符保持大寫,其余的被降低!
確實(shí),如果您檢查類 csxwtHeaders
用于表示HTTP請(qǐng)求(和響應(yīng))標(biāo)頭,您會(huì)看到它在添加鍵時(shí)規(guī)范化"鍵(在 normalize(String)
中):
/* 通過(guò)轉(zhuǎn)換為以下形式來(lái)規(guī)范化密鑰.* 第一個(gè)字符大寫,其余小寫.* key 假定為 ASCII*/私有字符串規(guī)范化(字符串鍵){...}
所以,雖然 csxwthcHttpTransportPipe
類(我的理解是這里是創(chuàng)建HTTP請(qǐng)求的地方,這也是之前添加的地方標(biāo)頭將添加到 HTTP 請(qǐng)求標(biāo)頭中)實(shí)際上添加 "Content-Type"
作為 csxwtHeaders
實(shí)例,因?yàn)榍懊嫣岬降膶?shí)現(xiàn)細(xì)節(jié),key 會(huì)被修改.
我可能是錯(cuò)的,但我不明白如何在不修補(bǔ)代碼的情況下更改它.奇怪的是,我不認(rèn)為這種規(guī)范化"的東西真的符合 RFC(盡管沒(méi)有檢查 RFC 關(guān)于標(biāo)頭大小寫的內(nèi)容).我很驚訝.實(shí)際上,您應(yīng)該提出問(wèn)題.
所以我在這里看到了三個(gè)選項(xiàng)(因?yàn)榈却迯?fù)可能不是一個(gè)選項(xiàng)):
- 自己修補(bǔ)代碼并重建 JAX-WS RI(具有這種方法的所有缺點(diǎn)).
- 為您的客戶嘗試另一種 JAX-WS 實(shí)現(xiàn),例如 CFX.
- 讓請(qǐng)求通過(guò)某種自定義代理來(lái)動(dòng)態(tài)修改標(biāo)頭.
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.
這篇關(guān)于jax-ws 將 Content-type 更改為 Content-Type 因?yàn)榉?wù)器是超敏感的的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!