jax-ws将Content-type更改为Content-Type,因为服务器是超敏感的

Esb*_*sen 11 java client header http jax-ws

我必须连接到一个实现效果不佳的服务器,它只能理解Content-Type(资本-T)而不是Content-type.我怎样才能让我的JAX-WS客户端发送Content-Type

我试过了:

Map<String, List<String>> headers = (Map<String, List<String>>)
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Run Code Online (Sandbox Code Playgroud)

不过headersnull.我究竟做错了什么?

Pas*_*ent 15

我必须连接到一个实现不好的服务器,它只能理解Content-Type(大写-T)而不是Content-type.如何让我的jax-ws客户端发送Content-Type?

我更多地挖了这个问题,遗憾的是,我害怕答案是:你做不到.让我分享一下我的发现.

首先,您在https://jax-ws.dev.java.net/guide/HTTP_headers.html 找到的代码不允许您访问未来HTTP请求的HTTP标头(尚未创建)此时,它允许您为发出请求设置其他HTTP标头(稍后将添加到HTTP请求中).

所以,null如果你put之前没有做任何事情,不要指望下面的代码不会返回(实际上,你只会得到你put在那里的东西):

((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Run Code Online (Sandbox Code Playgroud)

然后,我根据同一链接中提供的代码做了一点测试:

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);
Run Code Online (Sandbox Code Playgroud)

这是我在运行客户端代码时在HTTP请求中看到的内容:

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

你注意到了区别:只有X-Client-Version标题的第一个字符被保持在上面,其余的被降低了!

实际上,如果您检查c.s.x.w.t.Headers用于表示HTTP请求(和响应)标头的类,您将看到它在添加(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) {
     ...
 }
Run Code Online (Sandbox Code Playgroud)

所以,虽然这个c.s.x.w.t.h.c.HttpTransportPipe类(我的理解是这是创建HTTP请求的地方,这也是以前添加的标题将被添加到HTTP请求标头的地方)实际上"Content-Type"c.s.x.w.t.Headers实例中添加为密钥,密钥将被修改,因为前面提到的实现细节.

我可能错了,但我不知道如果不修补代码就可以改变它.奇怪的是,我不认为这种"正常化"的东西确实符合RFC(虽然没有检查RFC对标题的说法).我很惊讶.实际上,你应该提出一个问题.

所以我在这里看到三个选项(因为等待修复可能不是一个选项):

  • 自己修补代码并重建JAX-WS RI(具有此方法的所有缺点).
  • 为您的客户端尝试另一种类似CFX的JAX-WS实现.
  • 让请求通过某种自定义代理来动态修改标头.