web-dev-qa-db-ja.com

java Webサービスクライアント、httpヘッダーの追加

Wsdlでwsimportを使用してJava Webサービスクライアントを作成したら、httpリクエストに埋め込まれた各soapメッセージにAuthorizationヘッダーを設定する必要があります。javax.xml.wsのサブクラスを生成しました。サービス、どのようにして各送信要求にhttpヘッダーを追加できますか?

16
murungu

カスタムヘッダーを含むマップをBindingProviderに渡すことができます(MessageContext.HTTP_REQUEST_HEADERSプロパティを設定できると思います)。 Authorizationヘッダーを作成して渡します。

13
Femi

これが、Femiの回答に基づくコードです。

理解するのが少し難しいかもしれません。美しく動作します!

Service jaxwsService = Service.create(wsdlURL, serviceName);
Dispatch<SOAPMessage> disp = jaxwsService.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);

//Add HTTP request Headers
Map<String, List<String>> requestHeaders = new HashMap<>();
requestHeaders.put("Auth-User", Arrays.asList("BILL_GATES"));
disp.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);
19
Daniel Alexiuc

完全を期すため、および同様の状況で他のユーザーを支援するために、JAX-WS-handler-chainを使用したIMHOの最もクリーンなソリューションを示します。

1)別の(生成されていない)パッケージにサービスクラス(ポートクラスではない)をサブクラス化します。サービスクラス(およびそのパッケージ全体)はWSDLから生成された可能性が高いため、WSDLの変更後にサービスクラスを更新しても、サブクラスへの変更は失われません。

2)サービスサブクラスに次のように注釈を付けます(インポートjavax.jws.HandlerChain):

@HandlerChain(file="HandlerChain.xml")
public class MyService extends GeneratedService {

3)サービスサブクラスと同じパッケージ内にHandlerChain.xmlというファイルを作成します。つまり、MyServiceの横に次の内容を含めます。

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://Java.Sun.com/xml/ns/javaee">
    <handler-chain>
        <handler>
            <handler-name>co.codewizards.example.HttpHeaderExtensionSOAPHandler</handler-name>
            <handler-class>co.codewizards.example.HttpHeaderExtensionSOAPHandler</handler-class>
        </handler>
    </handler-chain>
</handler-chains>

ところで、複数の<handler>要素を追加できます。

そして、このファイルが本当にあなたのJARにあることを確認してください!たとえば、Mavenを使用する場合は、${project}/src/main/resources/ではなく${project}/src/main/Java/に配置するか、Javaフォルダーのリソースを含めるようにビルド構成を変更する必要があります!後者をお勧めします。これは、resources- folderに並列パッケージ構造を含めるのが面倒なので、リファクタリング中に忘れられることが多いためです。

4)HttpHeaderExtensionSOAPHandlerを実装します-これと同様です:

import static com.google.common.base.Preconditions.*;

import Java.util.*;

import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import co.codewizards.webservice.WebserviceContext;

public class HttpHeaderExtensionSOAPHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        checkNotNull(context, "context");

        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        checkNotNull(outboundProperty, "outboundProperty");

        if (outboundProperty.booleanValue()) {
            WebserviceContext<?, ?> webserviceContext = WebserviceContext.getThreadWebserviceContextOrFail();
            String something = (String) webserviceContext.___(); // my API method ;-)

            @SuppressWarnings("unchecked")
            Map<String, List<String>> requestHeaders = (Map<String, List<String>>) context.get(MessageContext.HTTP_REQUEST_HEADERS);
            if (requestHeaders == null) {
                requestHeaders = new HashMap<String, List<String>>();
                context.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);
            }
            requestHeaders.put(MyService.MY_CONSTANT, Collections.singletonList(something));
        }
        return true;
    }

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

    @Override
    public void close(MessageContext context) { }

    @Override
    public Set<QName> getHeaders() { return Collections.emptySet(); }
}

上記の例(および私の生産的なコード)では、HTTPリクエストヘッダーに渡されるデータをThreadLocale、つまり現在のスレッドのコンテキストから取得します。このWebserviceContextは私のカスタムクラスなので、データにアクセスするには独自の方法を実装する必要があります。

6
Marco

Daniel AlexiucとFemiの回答を補足するために、ここにこのドキュメントに基づくわずかに別の方法があります: https://javaee.github.io/metro/doc/user-guide/user-guide.html#adding-soap- headers-when-sending-requests

public class HelloClient {

   @WebServiceRef(wsdlLocation="http://localhost:8080/helloservice/hello?wsdl")
   static HelloService service;


   public HelloPort getHelloPort(){
       HelloPort helloPort = service.getHelloPort();

       Map<String, List<String>> requestHeaders = new HashMap<>();
       requestHeaders.put("Your_Header",Arrays.asList("Your_Header_value"));

       BindingProvider bindingProvider = (BindingProvider)helloPort;
       bindingProvider.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);

       return helloPort;
    }
}

これにより、ヘッダーがhttpリクエストに追加されます

1
Artem Coder

メッセージモードで送信する場合は、SOAPメッセージにMimeHeadersを渡すこともできます。これにより、最終的にhttpヘッダーに変換されます。つまり、

soapMessage.getMimeHeaders().addHeader("Authorization","Basic [md5]")
1
comeGetSome