java - 如何在 Java(或 C#)中使用摘要身份验证 HTTP 通过 HTTP 发送 SOAP 请求?

标签 java xml soap wsdl digest-authentication

我有一个网络服务,网址是 http://192.168.0.10/services/abc?wsdl
此 Web 服务器使用摘要身份验证,用户名是 admin,密码是 admin
我想将请求发送到此服务器

SOAP 请求 XML 为 SOAP_RQ.XML

 <soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:log="LogsGet" xmlns:mal="MalteseGlobal" xmlns:job="JobGlobal">
         <soapenv:Body>
             <log:LogsGetReq Cmd="Start" OpV="01.00.00" Sev="Info to critical"/>
          </soapenv:Body>
</soapenv:Envelope>     

Picture below description about SOAP communication over HTTP
我的代码:

 private static SOAPMessage createSOAPRequest(String username, String password) throws Exception {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();
        SOAPPart soapPart = soapMessage.getSOAPPart();
        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration("log", "LogsGet");
        envelope.addNamespaceDeclaration("mal", "MalteseGlobal");
        envelope.addNamespaceDeclaration("job", "JobGlobal");
        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement("LogsGetReq", "log");
        QName Cmd = new QName("Cmd");
        QName OpV = new QName("OpV");
        QName Sev = new QName("Sev");
        soapBodyElem.addAttribute(Cmd, "Start");
        soapBodyElem.addAttribute(OpV, "01.00.00");
        soapBodyElem.addAttribute(Sev, "Info to critical");
        //SOAP Header
        MimeHeaders hd = soapMessage.getMimeHeaders();
        hd.addHeader("UsernameToken", username);
        hd.addHeader("PasswordText", password);

        soapMessage.saveChanges();       
        return soapMessage;
    }

public void sendSoapRequest(String url, String username, String password) {
        try {
            // Create SOAP Connection
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            // Send SOAP Message to SOAP Server         
            SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(username, password, txtArea), url);
            // Process the SOAP Response               
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            soapResponse.writeTo(bos);
            System.out.println();  
            soapConnection.close();

        } catch (Exception e) {
            System.out.println("Error occurred while sending SOAP Request to Server");              
            e.printStackTrace();
        }
    }

当我发送请求时,我收到以下消息: 错误响应:(需要 401Authorization)

如果我发送请求,请使用curl工具( http://curl.haxx.se/download/curl-7.41.0.zip ) 命令行:curl.exe -X POST http://192.168.0.10/services/Maltese -H“内容类型:text/xml;字符集=utf-8”-H“SOAPAction:LogsGet”--digest -u admin:admin -d @SOAP_RQ.xml -v
我收到消息回复“OK”。

任何人都可以帮助我,如何使用 JAVA(或 C#)通过 HTTP 发送 SOAP 请求吗?

谢谢

最佳答案

// I used Apache HttpClient.
// For URL, you need to find end point URL.
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.HttpResponse;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.PrintWriter;
import java.io.StringWriter;

// Input parameter
String username = "";
String password = "";
String url = "";

// Variables 
int responseCode = 0;
String errorMessage = "";
String responseContent = "";
String content = ""

HttpResponse response;

try
{
    content = 
        "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:log=\"LogsGet\" xmlns:mal=\"MalteseGlobal\" xmlns:job=\"JobGlobal\">" + 
        "\n  <soapenv:Body>" +
        "\n    <log:LogsGetReq Cmd=\"Start\" OpV=\"01.00.00\" Sev=\"Info to critical\"/>" + 
        "\n  </soapenv:Body>" +
        "\n</soapenv:Envelope>";

    // Create the POST object and add the parameters
    HttpPost httpPost = new HttpPost(url);
    httpPost.addHeader("Content-Type", "text/xml; charset=utf-8");

    // Enable preemptive authentication within HttpClient so that HttpClient will 
    // send the basic authentications reponse before the server gives an unauthorized reponse. 
    String host = httpPost.getURI().getHost();
    int port = httpPost.getURI().getPort();   
    AuthScope authScope = new AuthScope(host, port);
    DefaultHttpClient httpClient = new DefaultHttpClient();
    UsernamePasswordCredentials credentials = new     UsernamePasswordCredentials(username, password);
    httpClient.getCredentialsProvider().setCredentials(authScope, credentials);   

    StringEntity input = new StringEntity(content);
    input.setContentType("application/json");
    httpPost.setEntity(input);   
    response = httpClient.execute(httpPost);

    if (response != null && response.getStatusLine() != null)
    {
        responseCode = response.getStatusLine().getStatusCode();
        responseContent = EntityUtils.toString(response.getEntity());
    }

    System.out.println("\n\n-----------------------------");
    System.out.println("\nResponse code: " + responseCode);
    System.out.println("\nResponse content: " + responseContent);
}
catch (Exception e)
{
    errorMessage  += "\nUnexpected Exception: " + e.getMessage();
    StringWriter sWriter = new StringWriter();
    PrintWriter pWriter = new PrintWriter(sWriter, true);
    e.printStackTrace(pWriter);
    errorMessage += "\n" + sWriter.getBuffer().toString();

    errorMessage += "\n------------Error Detail------------";
    errorMessage += "\n" + e;
    errorMessage += "\n" + e.getMessage();
    errorMessage += "\n" + e.getLocalizedMessage();
    errorMessage += "\n" + e.getCause();
    errorMessage += "\n" + Arrays.toString(e.getStackTrace());
    errorMessage += "\n" + e.printStackTrace();
    errorMessage += "\n------------------------------------";
}
finally
{
    if(response)
    {
        EntityUtils.consume(response.getEntity());    
    }
}

if(errorMessage != "")
{
    System.out.println("Error: " + errorMessage);
} 

关于java - 如何在 Java(或 C#)中使用摘要身份验证 HTTP 通过 HTTP 发送 SOAP 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28875642/

相关文章:

java - 使用递归传递具有基本情况的参数

java - Spring Batch - 无法初始化阅读器

java - 获取 403 : Forbidden when consuming SOAP service using apache cxf in java

web-services - 使用 CXF 在 WSDL 中的soapaction

java.lang.IllegalArgumentException : local part cannot be "null" when creating a QName

java - 从注释中获取值(value)

java - 掷骰子,有 50% 的几率掷出 6

java - 像谷歌浏览器一样在 jtabbedPane 中添加选项卡

c# - XmlSerializer 使用逗号(,)十进制符号反序列化十进制

javascript - 使用 javascript 漂亮地打印 XML