1

私は Netbeans を使用して Web サービス クライアント コード (クライアント スタイルの JAX-WS) を生成するので、Web サービス API を呼び出すことができます。

しかし、Web サービス API を呼び出すと、次の例外が発生します: com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 307: Temporary Redirect

なぜ私はこれを得るのですか?回避策は何ですか? 問題は web サービス自体にあるのではないことはわかっています。

4

2 に答える 2

0

約1か月前に同じ問題に直面しました。

WebサービスクライアントクラスはApacheCXFを使用して生成され、WebサービスはHTTPステータス307を返しました。これにより、同じ例外が発生しました。

Follow Redirectsプロパティがに設定されたsoapUIを使用した同じWebサービスメソッドの呼び出しtrueは成功し、必要なデータが返されました。

しばらくグーグルした後、このためにJAX-WSで次のリダイレクトを有効にするプロパティがないように見えました。

したがって、以下は現在機能しているコードですが、どの標準にも準拠しているかどうかはわかりません。

生成されたクライアントクラスが次のようになっていると仮定します。

// generated service class
public class MyWebServiceClient extends javax.xml.ws.Service {
    // ...
    private final QName portName = "...";
    // ...
    public RetrieveMyObjects getRetrieveMyObjects() {
        return super.getPort(portName, RetrieveMyObject.class);
    }
    // ...
}

// generated port interface
// annotations here
public interface RetrieveMyObjects {

    // annotations here
    List<MyObject> getAll();

}

さて、次のコードを実行すると:

MyWebServiceClient wsClient = new MyWebServiceClient("wsdl/location/url/here.wsdl");
RetrieveMyObjectsPort retrieveMyObjectsPort = wsClient.getRetrieveMyObjects();

wsClientRetrieveMyObjectsjavax.xml.ws.BindingProviderinterfacesのインスタンスであるインスタンスを返す必要があります。JAX-WSの表面には何も記載されていませんが、多くのコードがその事実に基づいているようです。次のようなことを実行することで、自分自身を安心させることができます。

if(!(retrieveMyObjectsPort instanceof javax.xml.ws.BindingProvider)) {
    throw new RuntimeException("retrieveMyObjectsPort is not instance of " + BindingProvider.class + ". Redirect following as well as authentication is not possible");
}

retrieveMyObjectsPortさて、それがインスタンスであることが確実な場合はjavax.xml.ws.BindingProvider、SOAPリクエストをシミュレートしてプレーンなHTTP POSTリクエストを送信できます(ただし、これは非常に不正確で醜いように見えますが、私の場合は機能し、グーグル中にこれ以上良いものは見つかりませんでした)。 Webサービスがリダイレクトステータスを応答として送信するかどうかを確認します。

// defined somewhere before
private static void checkRedirect(final Logger logger, final BindingProvider bindingProvider) {
    try {
        final URL url = new URL((String) bindingProvider.getRequestContext().get(ENDPOINT_ADDRESS_PROPERTY));
        logger.trace("Checking WS redirect: sending plain POST request to {}", url);
        final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setInstanceFollowRedirects(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "text/html; charset='UTF-8'");
        connection.setDoOutput(true);

        if(connection.getResponseCode() == 307) {
            final String redirectToUrl = connection.getHeaderField("location");
            logger.trace("Checking WS redirect: setting new endpoint url, plain POST request was redirected with status {} to {}", connection.getResponseCode(), redirectToUrl);
            bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, redirectToUrl);
        }
   } catch(final Exception e) {
       logger.warn("Checking WS redirect: failed", e);
   }
}

// somewhere at the application start
checkRedirect(logger, (BindingProvider) retrieveMyObjectsPort);

さて、このメソッドが行うことは次BindingProvider.ENDPOINT_ACCESS_PROPERTYのとおりです。retrieveMyObjectsPortつまり、このポートメソッドがSOAPリクエストを送信するURLを取得し、上記のようにプレーンなHTTPPOSTリクエストを送信します。次に、応答ステータスがであるかどうかをチェックし307 - Temporary Redirect(302や301などの他のステータスも含まれる場合があります)、そうである場合は、WebサービスがリダイレクトしているURLを取得し、指定されたポートに新しいエンドポイントを設定します。

私の場合、このcheckRedirectメソッドはWebサービスポートインターフェイスごとに1回呼び出され、すべてが正常に機能しているように見えます。

  1. リダイレクトは次のようなURLでチェックされますhttp://example.com:50678/restOfUrl
  2. Webサービスは次のようなURLにリダイレクトしますhttps://example.com:43578/restOfUrl(Webサービスクライアント認証が存在することに注意してください)-ポートのエンドポイントはそのURLに設定されます
  3. そのポートを介して実行された次のWebサービス要求は成功します

免責事項:私はWebサービスにまったく慣れていません。これは、この質問に対する解決策がないために何とか達成できたものです。ここで問題が発生した場合は、修正してください。

お役に立てれば

于 2012-03-19T00:22:37.053 に答える
0

はい、この投稿が古いことは知っていますが、同様のエラーが発生したため、誰かが私のソリューションから恩恵を受けると思いました。
私を最も悩ませたのは:

com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 200: OK

これは、不完全な応答ヘッダーを意味することが判明しました。どうやら jax-ws は、HTTP ヘッダーの検証も含む何らかの検証を行っているようです。そして、私が使用していたサーバーは空のヘッダーを送信していました。

ヘッダーに追加'application/soap+xml'した後、それは魅力のように機能しました。Content-Type

于 2012-11-07T10:51:50.193 に答える