繁体   English   中英

改进Java Soap客户端

[英]Improve a java soap client

我有一个Java soap客户端,它将XML请求发送到远程服务器并获取响应。 它可以工作,但是要花费太多时间从服务器发送和检索结果。 有什么方法可以加快我的肥皂客户的速度吗? 将超时设置为zéro之类的东西?

这是我的肥皂客户端的代码:


public class SoapHelper
{

  public String server = "";
  public String username = "";
  public String password = "";
  public String session = "";  // this is the session id returned by the server upon successful login
  private SOAPConnection con = null;
  private MessageFactory mf = null;

  public String service = "";
  public String method = "";
  public String request = "";  // this is what we send to the server
  public String response = "";  // this is what the server return to us

  public SoapHelper(String server)
  {
    this.server = server;
  }

  private String getURI()
  {
    return "https://" + this.server + this.session;
  }

  private SOAPMessage makeMessage(String nodeName, String xmlStr) throws Exception
  {

    SOAPMessage message = this.mf.createMessage();
    SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();

    envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/1999/XMLSchema-instance");
    envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/1999/XMLSchema");

    SOAPBody body = envelope.getBody();

    SOAPElement element = body.addChildElement(envelope.createName("ns1:" + this.method));
    element.addAttribute(envelope.createName("xmlns:ns1"), "urn:" + this.service);
    element.addAttribute(envelope.createName("ns1"), "http://schemas.xmlsoap.org/soap/encoding");

    SOAPElement ele2 = element.addChildElement(envelope.createName(nodeName));
    ele2.addAttribute(envelope.createName("xsi:type"), "xsd:string");
    ele2.addTextNode(xmlStr);

    message.saveChanges();

    return message;
  }

  private void doConnect()
  {
    try
    {
      SOAPConnectionFactory conFactory = SOAPConnectionFactory.newInstance();
      this.con = conFactory.createConnection();
      this.mf = MessageFactory.newInstance();
    }
    catch (Exception e)
    {
    }
  }

  public boolean doRequest(String service, String method, String xml)
  {
    this.service = service;
    this.method = method;
    this.request = "";
    this.request = xml;

    try
    {
      URL endpoint = new URL(this.getURI());
      SOAPMessage message = this.makeMessage("msgstr", this.request);
      SOAPMessage retval = this.con.call(message, endpoint);
      //extraction du XML en String lisible du message SOAP
      this.response = extractXML(retval);
    }
    catch (Exception e)
    {
      this.response = e.getMessage();
    }
    return true;
  }

  private String extractXML(SOAPMessage message) throws Exception
  {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    message.writeTo(out);
    String returnxml = new String(out.toByteArray());
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document document = db.parse(new InputSource(new StringReader(returnxml)));
    Element root = document.getDocumentElement();
    Node msg = root.getLastChild();

    return msg.getTextContent();
  }

  private String getSession() throws Exception
  {

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document document = db.parse(new InputSource(new StringReader(this.response)));
    Element root = document.getDocumentElement();

    return root.getAttribute("sessionid");
  }

  public void authenticate(String username, String password)
  {

    this.username = username;
    this.password = password;

    try
    {
      String xml = "<Message messageid='0'><Entity name='REF_LOGIN'>";
      xml += "<Property name='login_cd' value='" + this.username + "' type='string'/>";
      xml += "<Property name='password' value='" + this.password + "' type='string'/>";
      xml += "<Property name='machine_name' value='" + getMachineName() + "' type='string'/>";
      xml += "</Entity></Message>";
      doConnect();
      doRequest("Login", "Authenticate", xml);
      this.session = this.getSession();
    }
    catch (Exception e)
    {
      this.session = e.getMessage();
    }
  }

IMO,您不太可能使其速度大大提高并且仍然安全。

有机会大部分时间实际上是在网络开销中消耗的:

  • 网络延迟
  • 多次往返以建立安全的SSL / TLS连接,
  • 至少一次往返来登录会话,
  • 至少来回发送请求和接收回复,
  • (可能)网络拥塞,以及
  • (可能,但不太可能)额外的网络连接等,以获取XML模式。

现在,一些本可以潜在地优化。 例如:

  • 可以将模式本地缓存(如果实际上是在获取它们)。
  • 您可以切换为使用HTTP而不是HTTPS。
  • 如果您要向同一服务发送多个请求,则可以使用持久连接进行调查。

我的建议是使用客户端上的网络监视工具来真正了解网络流量。 然后找出以上哪一项是造成效果不佳的原因。 如果主要的原因是网络延迟(我怀疑),那么除了减少必须执行的往返次数外,您无能为力。

作为记录,我认为XML处理不太可能是导致性能问题的主要因素。 (但是您可以使用探查器来验证。)


将超时设置为zéro之类的东西?

没有任何魔术可以使网络延迟消失。 延迟是由物理定律引起的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM