改进Java Soap客户端

时间:2019-04-23 12:10:28

标签: java xml soap

我有一个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();
    }
  }

1 个答案:

答案 0 :(得分:1)

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

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

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

现在其中一些可以潜在地进行优化。例如:

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

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

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


  

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

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