Ручная отправка SOAP запросов в Java

Не так давно была опубликована заметка, по созданию SOAP Java SE клиента.  В этой заметке будет описан пример создания SOAP запроса «ручками», без использования сторонних библиотек.

Для создания тела xml запроса, используем класс StringBuilder. Использование StringBuilder/StringBuffer вместо работы с классом String при частом добавлении строк позволяет избежать создания множества экземпляров класса String в памяти.

    String body = sb.toString();
    byte[] buffer = new byte[body.length()];
    try {
         buffer = sb.toString().getBytes("UTF-8");
    } catch (UnsupportedEncodingException e1) {
         e1.printStackTrace();
    }

В этом участке кода создается один объект типа String, содержащий в себе тело запроса, далее мы его конвертируем в массив байтов с кодировкой UTF-8. В большинстве случаев параметр кодировки не требуется, т.е. можно просто вызвать

    sb.toString().getBytes()

Далее просто создается соединение и открывается. Здесь надо обратить внимание, что url должен содержать путь, без расширения *.wsdl, в отличии от работы с той же библиотекой KSOAP

    URL u = new URL("http://url_to_web_service_without_wsdl_exstension");
    URLConnection uc = u.openConnection();
    HttpURLConnection connection = (HttpURLConnection) uc;

Теперь самое важное — работа с заголовком запроса. Первые 2 строки отвечают за basic authentication(базовую аутентификацию). Для этого пару user:password Надо закодировать в Base64. Далее мы устанавливаем длину тела запроса, тип запроса: application/soap+xml;charset=UTF-8 и название вызываемого веб метода. В нашем случае это Registration. в wsdl его можно посмотреть по имени soapAction=»…»

       String authorization =org.kobjects.base64.Base64.encode("user:password".getBytes());
       connection.setRequestProperty("Authorization", "Basic "+authorization);
       connection.setDoOutput(true);
       connection.setDoInput(true);
       connection.setRequestProperty("Content-Length",
       String.valueOf(buffer.length));
       connection.setRequestMethod("GET");
       connection.setRequestProperty("Content-type", "application/soap+xml;charset=UTF-8");
       String soapAction = "http://NAMESPACE#NAME_SERVICE:Registration";
       connection.setRequestProperty("SOAPAction", soapAction);
По окончании формирования заголовков, мы открываем выходной поток, куда записываем наше тело запроса:
       try(OutputStream out = connection.getOutputStream()){
           out.write(buffer);
       }

По окончании записи проверяем ответ от сервера, он должен быть равен HttpURLConnection.HTTP_OK. Далее все очень просто — берем входной поток от веб сервиса, читаем ответ и парсим, используя возможности пакета javax.xml.parsers.

Полный листинг запроса:
    StringBuilder sb = new StringBuilder();
    sb.append("<soap:Envelope ");
    sb.append("xmlns:soap=");
    sb.append("\"http://www.w3.org/2003/05/soap-envelope\"");
    sb.append(" xmlns:ser=");
    sb.append("\"http://NAMESPACE\">\n");
    sb.append("<soap:Header/>\n");
    sb.append("<soap:Body>\n");
    sb.append("<ser:Registration>\r\n");
    sb.append("<ser:Organisation>Organization</ser:Organisation>\r\n");
    sb.append("<ser:FullName>FIO</ser:FullName>\r\n");
    sb.append("<ser:PhoneNumber>111-11-11</ser:PhoneNumber>\r\n");
    sb.append("<ser:JobTitle>Scientist</ser:JobTitle>\r\n");
    sb.append("<ser:Email>developer@it-notepad.com</ser:Email>\r\n");
    sb.append("<ser:InternalPhoneNumber>111</ser:InternalPhoneNumber>\r\n");
    sb.append("<ser:MobileNumber>8-111-111-11-11</ser:MobileNumber>\r\n");
    sb.append("<ser:UserID>LLL</ser:UserID>\r\n");
    sb.append("<ser:ErrorText>Text</ser:ErrorText>\r\n");
    sb.append("</ser:Registration>\r\n");
    sb.append("</soap:Body>\r\n");
    sb.append("</soap:Envelope>");
    String body = sb.toString();
    byte[] buffer = new byte[body.length()];
    try {
         buffer = sb.toString().getBytes("UTF-8");
    } catch (UnsupportedEncodingException e1) {
         e1.printStackTrace();
    }

    try{

       URL u = new URL("http://url_to_web_service_without_wsdl_exstension");
       URLConnection uc = u.openConnection();
       HttpURLConnection connection = (HttpURLConnection) uc;

       String authorization =org.kobjects.base64.Base64.encode("user:password".getBytes());
       connection.setRequestProperty("Authorization", "Basic "+authorization);
       connection.setDoOutput(true);
       connection.setDoInput(true);
       connection.setRequestProperty("Content-Length",
       String.valueOf(buffer.length));
       connection.setRequestMethod("GET");
       connection.setRequestProperty("Content-type", "application/soap+xml;charset=UTF-8");
       String soapAction = "http://NAMESPACE#NAME_SERVICE:Registration";
       connection.setRequestProperty("SOAPAction", soapAction);

       try(OutputStream out = connection.getOutputStream()){
           out.write(buffer);
       }

       if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            try(InputStreamReader is = new InputStreamReader(connection.getInputStream(),"UTF-8")){

                try(BufferedReader rd = new BufferedReader(is)){
                    StringBuilder strBuildReturn = new StringBuilder();
                    String line;
                    while ((line = rd.readLine()) != null){
                        System.out.println(line);
                        strBuildReturn.append(line);
                    }
                    connection.disconnect();

                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder builder = null;
                    try{
                        builder = factory.newDocumentBuilder();
                        try(StringReader strRead =   new StringReader(strBuilderReplace.toString())){
		            InputSource ins = new InputSource(strRead);
                            Document doc = builder.parse(ins);
                            doc.getDocumentElement().normalize();
                            NodeList nList = doc.getElementsByTagName("RegistrationResponse");

                            for (int temp = 0; temp < nList.getLength(); temp++) {
                               Node nNode = nList.item(temp);
                               System.out.println("Element :" + nNode.getNodeName());

                               if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                                  Element eElement = (Element) nNode;
                                  String userId = eElement.getElementsByTagName("UserID").item(0).getTextContent();
                                  boolean status = Boolean.valueOf(eElement.getElementsByTagName("return").item(0).getTextContent());
                                  ResponseAuth1C responseObj = new ResponseAuth1C(userId, status);
                             
                               }
                            }
                        }
                    } catch (ParserConfigurationException|SAXException e) {
                         e.printStackTrace();
                    }
                }
            }
          
       } else {
            try(InputStreamReader eis = new InputStreamReader(connection.getErrorStream())){
            errorHandler(eis);
       }

    }catch (IOException e) {
       System.err.println(e);
    }
    return null;

Leave a Reply

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.