【问题标题】:jax-ws change Content-type to Content-Type because server is hyper sensitivejax-ws 将 Content-type 更改为 Content-Type 因为服务器是超敏感的
【发布时间】:2011-01-23 06:15:21
【问题描述】:

我必须连接到一个执行不佳的服务器,该服务器只能理解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);

但是headersnull。我做错了什么?

【问题讨论】:

    标签: java http header client jax-ws


    【解决方案1】:

    我必须连接到一个执行不佳的服务器,该服务器只理解 Content-Type(capital-T) 而不是 Content-type。如何让我的 jax-ws 客户端发送 Content-Type?

    我对这个问题进行了更多研究,但遗憾的是,恐怕答案是:你不能。让我分享一下我的发现。

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

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

    ((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 请求中看到的内容:

    发布 /q2372336/addnumbers HTTP/1.1 内容类型: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 主机:本地主机:8080 连接:保持活动 内容长度:249

    您注意到区别了吗:只有X-Client-Version 标头的第一个字符保持大写,其余的被降低!

    事实上,如果您检查用于表示 HTTP 请求(和响应)标头的类 c.s.x.w.t.Headers,您会看到它在添加键时“规范化”了键(在 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) {
         ...
     }
    

    所以,虽然c.s.x.w.t.h.c.HttpTransportPipe 类(我的理解是这是创建 HTTP 请求的位置,这也是之前添加的标头将添加到 HTTP 请求标头的位置)实际上添加了 "Content-Type" 作为c.s.x.w.t.Headers 实例中的键,由于前面提到的实现细节,该键将被修改。

    我可能是错的,但我不明白如何在不修补代码的情况下更改它。奇怪的是,我不认为这种“规范化”的东西真的符合 RFC(尽管没有检查 RFC 关于标头大小写的内容)。我很惊讶。其实你应该raise an issue

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

    • 自己修补代码并重建 JAX-WS RI(具有这种方法的所有缺点)。
    • 为您的客户尝试其他 JAX-WS 实现,例如 CFX。
    • 让请求通过某种自定义代理来动态修改标头。

    【讨论】:

    • 我现在已经使用了自定义代理......丑得要命,想从我的代码中删除这个丑陋的 mofo。那好吧。 C'est la via
    • @EsbenP 如果您对此提出问题,请使用链接更新问题。我真的很想从 JAX-WS RI 开发人员那里得到一些反馈。
    【解决方案2】:

    您可以从 RequestContext 修改 HTTP 标头。如果您有权访问端口对象,则可以将其转换为 javax.xml.ws.BindingProvider,这将使您能够访问 RequestContext。

    您可能还想删除未接受的“Content-type”标头。

    这个页面更详细地展示了如何做到这一点:https://jax-ws.dev.java.net/guide/HTTP_headers.html

    如果您需要更多代码示例,或者如果您粘贴一些代码,我可以告诉您如何修改它。

    【讨论】:

    • 链接坏了,我也试过 msg.getMimeHeaders() 然后 removeHeader 或 addHeader 甚至 removeAllHeaders 都没有用,矢量支持标题似乎不可变
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 2012-07-28
    • 2012-07-11
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    相关资源
    最近更新 更多