#java #xml #soap
#java #xml #soap
Вопрос:
У меня есть серверное приложение Java, которое выполняет некоторые вызовы Soap на другой удаленный сервер.
Я поместил свое приложение Java server на удаленный сервер с tomcat 8.5. И когда я выполняю вызовы Soap, это занимает вдвое больше времени, тогда как с моего локального компьютера с tomcat 8.5 в Eclipse это происходит быстрее.
Вы знаете, почему?
Вот код для моего soap-клиента :
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. Можете ли вы предоставить какой-нибудь код?? И быть немного более конкретным?
2. Какой тип кода? мой Soap-клиент?
Ответ №1:
Скорее всего, это проблема с пропускной способностью сети (если не другие), потому что, когда вы отправляете сообщение SOAP с одного компьютера на другой удаленный компьютер, оно должно перемещаться туда и обратно в сеть, и если размер сообщения огромен, пропускная способность сети должна быть проблемой и занимать много времени.
В качестве примера.
Если время перехода по сети = 500 мс
SOAP servic = 400 мс
Тогда общее время для удаленного сервера = 400 500 мс (что ~ 2 * 400 мс).
Вот несколько советов, чтобы разобраться в этом.
1) Попробуйте записать, сколько времени сервер потратил на обработку, точку входа до конца обслуживания, если она точно такая же или близка к тому, что вы получаете на локальном, тогда доказано, что это только сетевая проблема.
Проблемы с задержкой в сети могут быть решены многими способами. Выбор ближайшего центра обработки данных, туннелирование, подключение к выделенной сети и т. Д.
2) Если это не так, возможно, вы пытаетесь подключиться к удаленной базе данных или чему-то еще в службе SOAP, что снова может вызвать проблемы с пропускной способностью сети или что-то еще (например, пропускная способность базы данных или отсутствие индексов или огромные данные по сравнению с локальными), но это доказывает, что это не проблема с пропускной способностью сети, и вам нужно это решить.
Надеюсь, это дает некоторый контекст, хотя для получения точного ответа вам нужно добавить больше деталей к вашему вопросу.
Комментарии:
1. Спасибо за ваш ответ. Я сделал несколько журналов для своей службы. И я могу подтвердить, что время для службы на удаленном сервере медленнее, чем на локальном. И именно процесс soap занимает двойное время на удаленном сервере.
2. Итак, если это проблема с пропускной способностью сети, как мне ее решить?