8

少し前もっての情報:

SOAP サービスがあります (JAX-WS (エンドポイント クラス) を使用してホストされていますが、それは重要ではないと思います)。

クライアント (C#) を生成する Visual Studio で問題なく Web サービスに接続して使用できます。

Eclipse Web ツール (新規 --> その他 --> Web サービス --> Web サービス クライアント) を使用して Java クライアントを生成しました。

次に、クライアントをテストする JUnit テストを作成しました。テストは成功しますが、実行に非常に時間がかかります。各サービス コールには 300 秒かかります (2 ~ 3 秒かかります)。さらに、コンピューターの速度は関係ありません。非常に遅い仕事用のラップトップでこれを実行すると、高速な家庭用マシンで実行した場合と同じ時間がかかります。

org.apache.axis.encoding.DeserializationContext 内の次の関数への軸コードにデバッグしました。

public void parse() throws SAXException
    {
        if (inputSource != null) {
            SAXParser parser = XMLUtils.getSAXParser();
            try {
                parser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
                parser.parse(inputSource, this);

                try {
                    // cleanup - so that the parser can be reused.
                    parser.setProperty("http://xml.org/sax/properties/lexical-handler", nullLexicalHandler);
                } catch (Exception e){
                    // Ignore.
                }

当然のことですが、parser.parse() の呼び出しに 300 秒かかっています。Web サービスからの は非常に短いため、解析にそれほど時間はかかりません。

誰かが疑問に思っている場合に備えて、パーサーの実際のタイプはcom.sun.org.apache.xerces.internal.jaxp.SAXParserImpl

ソースを持っていないため、デバッグできません (そして、一般的に使用されるライブラリの奥深くで 50 の呼び出しをデバッグするのにうんざりしています)。

私は現在、Sun からのパッケージを含めるためにプロファイラーを実行しています。完了したら、その結果を投稿します(これらのパッケージをすべて追加すると、テストが大幅に遅くなります)

私は走っていてEclipse 3.5.1、使っていますaxis 1.4

編集:

JUnit テストは次のとおりです。

@Test
public void testExecuter() throws IOException, InterruptedException, RemoteException, ServiceException
{
    //Listener l = new Listener(3456);
    //l.start();
    Executer exec = new ExecuterServiceLocator().getExecuterPort();
    //Executer exec = new ExecuterProxy("http://localhost:3456/Executer");
    System.out.println("executer created");
    _return remote = exec.execute("perl -e \"print 5\"", new EvAction[0]);
    System.out.println("after call 1");
    assertEquals("5", remote.getStdout());
    assertEquals("", remote.getStderr());
    assertEquals(0, remote.getReturnCode());
}

注: 実行者を作成する両方の方法で同じことが起こります

編集2:

サービスを開始するために使用しているコードは次のとおりです。

public static void main(String[] args) {
    Endpoint.create(new Executer()).publish("http://localhost:3456/Executer");
}

現在、単一のマシンで開発しているだけなので、URL を投稿できません。ただし、http://localhost:3456/Executer?WSDLにアクセスすると生成される WSDL は次のとおりです。

<!--
 Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
-->
−
<!--
 Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
-->
−
<definitions targetNamespace="http://executer/" name="ExecuterService">
−
<types>
−
<xsd:schema>
<xsd:import namespace="http://executer/" schemaLocation="http://localhost:3456/Executer?xsd=1"/>
</xsd:schema>
</types>
−
<message name="Execute">
<part name="parameters" element="tns:Execute"/>
</message>
−
<message name="ExecuteResponse">
<part name="parameters" element="tns:ExecuteResponse"/>
</message>
−
<message name="IOException">
<part name="fault" element="tns:IOException"/>
</message>
−
<message name="InterruptedException">
<part name="fault" element="tns:InterruptedException"/>
</message>
−
<portType name="Executer">
−
<operation name="Execute">
<input message="tns:Execute"/>
<output message="tns:ExecuteResponse"/>
<fault message="tns:IOException" name="IOException"/>
<fault message="tns:InterruptedException" name="InterruptedException"/>
</operation>
</portType>
−
<binding name="ExecuterPortBinding" type="tns:Executer">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
−
<operation name="Execute">
<soap:operation soapAction=""/>
−
<input>
<soap:body use="literal"/>
</input>
−
<output>
<soap:body use="literal"/>
</output>
−
<fault name="IOException">
<soap:fault name="IOException" use="literal"/>
</fault>
−
<fault name="InterruptedException">
<soap:fault name="InterruptedException" use="literal"/>
</fault>
</operation>
</binding>
−
<service name="ExecuterService">
−
<port name="ExecuterPort" binding="tns:ExecuterPortBinding">
<soap:address location="http://localhost:3456/Executer"/>
</port>
</service>
</definitions>

編集:

これが問題を引き起こしている可能性があると思います:

TCPMonitor を使用して SOAP 要求を調べたところ、クライアントが HTTP/1.0 を話し、サーバーが HTTP/1.1 を話していることに気付きましたが、これが問題の原因であるかどうかはわかりません。私は現在、クライアントに HTTP/1.1 を話させる方法を見つけようとしています。

誰かが疑問に思っている場合に備えて、SOAP メッセージを次に示します。

POST /Executer HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: USENBOONETL1C:2222
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 354

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><Execute xmlns="http://executer/"><arg0 xmlns="">perl -e &quot;print 5&quot;</arg0></Execute></soapenv:Body></soapenv:Envelope>

と応答:

HTTP/1.1 200 OK
Content-type: text/xml;
charset="utf-8"
Content-length: 266

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:ExecuteResponse xmlns:ns2="http://executer/"><return><stdout>5</stdout><stderr></stderr><returnCode>0</returnCode></return></ns2:ExecuteResponse></S:Body></S:Envelope>

編集:

ついに!HTTP クライアントを CommonsHTTPClient に変更し、HTTP/1.1 を使用すると問題が修正されることがわかりました。

これを修正したクライアントに追加したコードは次のとおりです。

BasicClientConfig basicClientConfig = new BasicClientConfig();
SimpleChain simpleChain = new SimpleChain();

simpleChain.addHandler(new CommonsHTTPSender());
basicClientConfig.deployTransport("http", simpleChain);

ExecuterServiceLocator l = new ExecuterServiceLocator(basicClientConfig);
...

注:クラスパスにcommon-httpclient.jarとを追加する必要があります。common.codec.jar

4

4 に答える 4

2

同じ問題が発生し、http バージョンを変更して解決しました。

これを行う簡単な方法は、スタブ クラス内で Call インスタンスの setProperty メソッドを呼び出すことです。

_call.setProperty(MessageContext.HTTP_TRANSPORT_VERSION,HTTPConstants.HEADER_PROTOCOL_V11);
于 2011-12-06T13:58:37.347 に答える
1

あなたの問題はまさに私が今直面しているものです。そして面白いことに、私はほぼ同じサイクルを経てきました (エンドポイント サービス、.net クライアントは正常に動作し、Eclipse で生成されたクライアントの処理には 5 分かかります)。更新と解決策を投稿していただき、本当にありがとうございます。私はJavaに精通していないので、Eclipseで生成された同じクライアントコードにソリューションを適用したかどうか尋ねてもよろしいですか? それともまったく違うことをしましたか?Eclipse で生成されたクライアント コードを変更した場合、それらの行を正確にどこに追加しましたか?

ありがとう、そして私は本当に助けに感謝します:)

乾杯、アーラッシュ

于 2010-10-10T05:25:37.380 に答える
1

1) C# クライアントと Java クライアントがまったく同じ要求をサーバーに送信していることを確認します。Jetty を使用している場合、リクエスト ログを有効にすると、必要なデータが得られる可能性があります。

2) SAX パーサーがクライアント上で実行を開始すると、生成されたクライアントのメソッドを直接または間接的に呼び出すコールバックが作成されます。生成されたクライアント メソッドの最初と最後 (および/またはreturns) にブレークポイントを設定し、これらを使用して遅延が発生する場所を特定できる必要があります。

(ところで、SAX API では、 などの URL がhttp://xml.org/sax/properties/lexical-handlerプロパティ名を識別するためにローカルで使用されます。そのアドレスでは何も検索されません。詳細については、 http: //xerces.apache.org/xerces2-j/properties.htmlを参照してください。情報。)

于 2010-01-04T16:35:10.123 に答える
0

ほとんどの場合、タイムアウトです。パーサーがインターネット (DTD、XSD など) から何かをダウンロードしようとしている可能性がありますが、プロキシ/ファイアウォールの背後にいます。

テストを実行して何が起こっているかを確認するときは、サーバーのスタック トレースを取得してみてください (例: jps/jstat)。

于 2009-12-31T18:44:41.817 に答える