java 使用 JAX-WS:如何设置用户代理属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5639695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:02:19  来源:igfitidea点击:

Using JAX-WS: How can I set the user agent property

java

提问by soulTower

I've searched on this and found a few near misses. I've created a java client to consume a web service using JAX-WS. Is there a way when using JAX to set the HTTP_USER_AGENT value? I would like to have my web service log when specific clients (mine) access it so I wanted a customized value.

我对此进行了搜索,发现了一些未遂事件。我已经创建了一个 Java 客户端来使用 JAX-WS 来使用 Web 服务。使用 JAX 设置 HTTP_USER_AGENT 值时有没有办法?当特定客户端(我的)访问它时,我希望拥有我的 Web 服务日志,因此我想要一个自定义值。

I've seen options where you set it in the system properties but this doesn't seem to work. The generated JAX classes don't seem to have a direct reference to the connection object so I don't see how I can manipulate those classes.

我已经看到您在系统属性中设置它的选项,但这似乎不起作用。生成的 JAX 类似乎没有对连接对象的直接引用,所以我看不到如何操作这些类。

Any help would be great. Thanks ST

任何帮助都会很棒。谢谢 ST

回答by dertoni

The solution to this kind of problem in JAX-WS is to implement a SoapMessage Handler (Interface: SOAPHandler< SOAPMessageContext >). Within that handler you insert your HTTP header into maybe already existing headers, then you give control to the next handler in the handler chain.

在 JAX-WS 中解决这类问题的方法是实现一个 SoapMessage Handler(接口:SOAPHandler<SOAPMessageContext>)。在该处理程序中,您将 HTTP 标头插入可能已经存在的标头中,然后将控制权交给处理程序链中的下一个处理程序。

The concept of this handler chain is kind of nice, you can have small classes for a very specific purpose (Security, Logging etc.).

这个处理程序链的概念很好,您可以为非常特定的目的(安全、日志记录等)创建小类。

In your client you configure the handler chain prior to sending any request:

在您的客户端中,您在发送任何请求之前配置处理程序链:

// HandlerChain installieren
Binding binding = ((BindingProvider) port).getBinding();
List hchain = binding.getHandlerChain();
if (hchain == null) {
  hchain = new ArrayList();
}
hchain.add(new HTTPUserAgentHandler());
binding.setHandlerChain(hchain);

And here is the code for the HTTPUserAgentHandler:

这是 HTTPUserAgentHandler 的代码:

public class HTTPUserAgentHandler implements SOAPHandler<SOAPMessageContext> {

  @Override
  public boolean handleMessage(SOAPMessageContext context) {
      boolean request = ((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();

      if (request) {
          @SuppressWarnings("unchecked")
          Map<String, List<String>> headers = (Map<String, List<String>>) context
                  .get(MessageContext.HTTP_REQUEST_HEADERS);
          if (null == headers) {
              headers = new HashMap<String, List<String>>();
          }
          headers.put("HTTP_USER_AGENT", Collections.singletonList("user_agent"));
          context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
      }
      return true;
  }

  @Override
  public boolean handleFault(SOAPMessageContext context) {
      return true;
  }

  @Override
  public void close(MessageContext context) {}

  @Override
  public Set<QName> getHeaders() {
      return null;
  }

}

回答by jtahlborn

not sure if this is the best/most direct way to do it, but i think you could add a custom javax.xml.ws.handler.Handler to the handler chain in the dispatch javax.xml.ws.Binding. in the Handler, you should be able to set a custom map of extra http headers on the outgoing MessageContext using the MessageContext.HTTP_REQUEST_HEADERS property.

不确定这是否是最好/最直接的方法,但我认为您可以将自定义 javax.xml.ws.handler.Handler 添加到调度 javax.xml.ws.Binding 中的处理程序链中。在处理程序中,您应该能够使用 MessageContext.HTTP_REQUEST_HEADERS 属性在传出的 MessageContext 上设置额外 http 标头的自定义映射。

回答by Vladimir Dyuzhev

Let me question the idea of having HTTP header first.

让我质疑首先拥有 HTTP 标头的想法。

A more correct (WS-centric) approach is to set SOAP Header, not HTTP header. Consider this: SOAP messages can be delivered not only by HTTP, but by JMS, SMTP or custom transports. By requiring to have user-agent HTTP Header, you unnecessary tie you code to only one transport, albeit currently prevailing.

更正确(以 WS 为中心)的方法是设置 SOAP 标头,而不是 HTTP 标头。考虑一下:SOAP 消息不仅可以通过 HTTP 传递,还可以通过 JMS、SMTP 或自定义传输传递。通过要求拥有用户代理 HTTP 标头,您不必将代码绑定到一种传输方式,尽管目前普遍存在。

This is the reason BTW why JAX-WS have no notion of HTTP headers except in handlers.

这就是为什么 JAX-WS 除了处理程序之外没有 HTTP 标头概念的原因。

And (of course) StackOverlow knowshow to create SOAP headers.

而且(当然)StackOverlow知道如何创建 SOAP 标头。