Eclipse生成的Web服务客户端非常慢

tst*_*ter 8 java eclipse axis web-services

一点前面的信息:

我有一个SOAP服务(使用JAX-WS(Endpoint类)托管,但我认为这不重要).

我可以使用Visual Studio生成客户端(C#)来连接并使用Web服务.

我使用Eclipse Web Tools生成了一个Java客户端(新的 - >其他 - > Web服务 - > Web服务客户端).

然后我写了一个JUnit测试来测试客户端.测试通过,但运行需要很长时间.每次服务呼叫需要300秒(给予或花费几秒钟).此外,计算机的速度并不重要.如果我在非常慢的工作笔记本电脑上运行它,它需要花费相同的时间,就好像我在快速的家用机器上运行它.

我已经调试了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.
                }
Run Code Online (Sandbox Code Playgroud)

没有惊喜,但是对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());
}
Run Code Online (Sandbox Code Playgroud)

注意:创建Executer的两种方式都会发生相同的事情

EDIT2:

这是我用来启动服务的代码:

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

我不能发布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>
Run Code Online (Sandbox Code Playgroud)

编辑:

我认为这可能会导致一个问题:

我使用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>
Run Code Online (Sandbox Code Playgroud)

和回应:

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>
Run Code Online (Sandbox Code Playgroud)

编辑:

最后!结果是将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);
...
Run Code Online (Sandbox Code Playgroud)

注意:您必须添加common-httpclient.jarcommon.codec.jar到classpath中.

Dan*_*lau 1

1) 验证 C# 和 Java 客户端是否向服务器发送完全相同的请求。如果您使用 Jetty,打开请求日志记录可能会为您提供所需的数据。

2) 一旦 SAX 解析器开始在客户端上运行,它将进行回调,最终直接或间接地调用生成的客户端中的方法。您应该能够在return生成的客户端方法的开头和结尾(和/或多个)设置断点,并使用它们来确定延迟发生的位置。

(顺便说一句,在 SAX API 中,诸如此类的 URLhttp://xml.org/sax/properties/lexical-handler在本地用于标识属性名称;不会在该地址中查找任何内容。有关更多信息,请参阅http://xerces.apache.org/xerces2-j/properties.html信息。)