4

Exchange Web サービス用のカスタム Java クライアントを作成しようとしています。EWS の Services.wsdl ファイルからここwsimportで説明されているように、ツールを使用してクライアント スタブを生成しました。そして今、これらのスタブを使用するコードを書きました。次の例外が発生しています:

Exception in thread "main" com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2   counts of InaccessibleWSDLException.

java.io.IOException: Got Server returned HTTP response code: 401 for URL: https://host.domain.com/ews/Services.wsdl while opening stream from https://host.domain.com/ews/Services.wsdl
java.io.IOException: Got Server returned HTTP response code: 401 for URL: https://host.domain.com/ews/Services.wsdl?wsdl while opening stream from https://host.domain.com/ews/Services.wsdl?wsdl

at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.<init>(Unknown Source)
at com.microsoft.schemas.exchange.services._2006.messages.ExchangeWebService.<init>(ExchangeWebService.java:58)
at com.xyz.abc.EWSJavaAPI.ExchangeAuthenticator.getExchangeServicePort(ExchangeAuthenticator.java:33)
at com.xyz.abc.test.ExchangeDevelopmentTest.main(ExchangeDevelopmentTest.java:35)

上記のように、生成されたクライアント スタブを使用するExchangeDevelopmentTest別のクラスを使用するクライアントがあります。しかし、スタック トレースで、おそらく JDK の JAR である不明なソースからエラーが発生しました。ExchangeAuthenticatorExchangeWebService

は、不正アクセス用であるとIOException言っています。HTTP response code: 401しかし、ユーザー名とパスワードを正しく指定し、必要な証明書もキーストアに含めました。この例外がどこから来ているのか、私はまったく方向性がありません。

私が書いたクラスのコード:

ExchangeAuthenticator

public class ExchangeAuthenticator {    
/**
 * Obtains an authenticated ExchangeServicePortType with given credentials.
 *     
 */
    public ExchangeServicePortType getExchangeServicePort(String username, String password, String domain, URL wsdlURL) throws MalformedURLException {
        // Concatinate our domain and username for the UID needed in authentication.
        String uid = "domain" + "\\" + "uname";

        // Create an ExchangeWebService object that uses the supplied WSDL file, wsdlURL.
        ExchangeWebService exchangeWebService = new ExchangeWebService(wsdlURL, new QName("<a href=\"http://schemas.microsoft.com/exchange/services/2006/messages\">http://schemas.microsoft.com/exchange/services/2006/messages</a>", "ExchangeWebService"));
        ExchangeServicePortType port = exchangeWebService.getExchangeWebPort();
        // Supply your username and password when the ExchangeServicePortType is used for binding in the SOAP request.
        ((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, uid);
        ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);

        return port;
    }
}

ExchangeDevelopmentTest

public class ExchangeDevelopmentTest {    
    public static void main (String[] args) {
        ExchangeAuthenticator exchangeAuthenticator = new ExchangeAuthenticator();

        // Print statement so we can easily see where our statements start in the Java console.
        System.out.println("Let's get started!");

        try {
            // Create a URL object which points at the .wsdl we deployed in the previous step.
            URL wsdlURL = new URL("https://172.17.245.196/ews/Services.wsdl");
            //URL wsdlURL = new URL("<a href=\"https://172.17.245.196/ews/Services.wsdl\">https://172.17.245.196/ews/Services.wsdl</a>");
            // Call to the class we just created to return an ExchangeServicePortType with authentication credentials.
            ExchangeServicePortType port = exchangeAuthenticator.getExchangeServicePort("uname", "password@123", "domain", wsdlURL);

            // Prints out the default toString() for the ExchangeServicePortType.
            System.out.println(port.toString());
        } catch (MalformedURLException ex) {
            // Catch any errors that may occur.
            Logger.getLogger(ExchangeDevelopmentTest.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.getMessage()+"\n"+ex.getStackTrace());
        }
    }
}

ExchangeWeb サービス

wsimportツール、他のコンストラクター、およびメソッドが削除された JAX-WS によって生成されます。super(ここでServiceはクラス) コンストラクターを呼び出す 58 行目のコンストラクターのみが保持されます。

@WebServiceClient(name = "ExchangeWebService", targetNamespace =     "http://schemas.microsoft.com/exchange/services/2006/messages", wsdlLocation = "file:/C:/Services.wsdl")
public class ExchangeWebService extends Service
{ 
    private final static URL EXCHANGEWEBSERVICE_WSDL_LOCATION;
    private final static WebServiceException EXCHANGEWEBSERVICE_EXCEPTION;
    private final static QName EXCHANGEWEBSERVICE_QNAME = new QName("http://schemas.microsoft.com/exchange/services/2006/messages", "ExchangeWebService");

    static {
        URL url = null;
        WebServiceException e = null;
        try {
            url = new         URL("file:/C:/workspace/Server%20files/Client%20files/Services.wsdl");
        } catch (MalformedURLException ex) {
            e = new WebServiceException(ex);
        }
        EXCHANGEWEBSERVICE_WSDL_LOCATION = url;
        EXCHANGEWEBSERVICE_EXCEPTION = e;
    }

    //other constructos & methods removed
    //line 58
    public ExchangeWebService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }    
}
4

2 に答える 2

6

ローカル コピーを使用できるのに、なぜリモートの WSDL ドキュメント ファイル (およびスキーマ ファイル) にアクセスするのでしょうか。もちろん、エンドポイントにアクセスするにはセキュリティが必要です。

まず、環境に応じたクラスローダが必要です。

// Java EE Enviroment
ClassLoader cl = Thread.currentThread().getContextClassLoader();

// Java Standalone Enviroment
ClassLoader cl = ClassLoader.getSystemClassLoader();

次に、プロジェクトの WSDL ドキュメント ファイル (および必要に応じてスキーム ファイル) のコピーをローカルに保存します。

URL wsdlLocation = cl.getResource("com/mahesha999/ExchangeWebService.wsdl");
QName qName = new QName(
    "http://schemas.microsoft.com/exchange/services/2006/messages", 
    "ExchangeWebService"
);

ExchangeWebService exchangeWebService = new ExchangeWebService(wsdlLocation, 
        qName);
ExchangeServicePortType port = exchangeWebService.getExchangeWebPort();

Web サービス エンドポイントにアクセスするために認証が必要な場合、最も基本的な形式は次のとおりです。

BindingProvider provider = (BindingProvider) port;
Map<String, Object> context = provider.getRequestContext();
context.put(BindingProvider.USERNAME_PROPERTY, username);
context.put(BindingProvider.PASSWORD_PROPERTY, password);

証明書などを扱う必要がある場合は、Securing WebLogic Web Servicesを参照してください。

于 2013-10-08T14:30:12.747 に答える
1

この方法でユーザー名とパスワードを追加しましたか?

    ShopingCart sc = scs.getShopingCartPort();
    Map requestContext = ((BindingProvider)sc).getRequestContext();
    requestContext.put(BindingProvider.USERNAME_PROPERTY, userName);
    requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);

問題のクライアント コードを指定していません。プロキシを使用していますか?次に、上記でプロキシのユーザー名とパスワードを指定する必要があります。

于 2013-10-08T11:49:12.277 に答える