使用Java和WS Security将SOAP消息发送到服务:内部服务器错误

时间:2013-12-09 19:03:23

标签: java xml soap

我们的团队通过soapUI向远程服务发送请求并收集回复。为了使这个过程自动化,我在下面的教程中指导了一个简单的Java应用程序。

http://drumcoder.co.uk/blog/2011/oct/18/httpclient-client-side-certificates/

代码如下。

背景:

目前,我们正在使用soapUI发送和接收消息。我们为请求指定密钥库,并且必须在发送之前应用传出的WSS。收到响应后,我们手动将其复制并粘贴到txt文件。当有数百个请求要处理时,这会非常繁琐且耗时,因此我们正在制作一个简单的Java应用程序来运行所有请求并保存相应的响应。我们使用了上面的教程,但它没有用。

什么工作?

我们当前手动将SOAP请求保存到xml文件,然后使用java应用程序成功加载,解析并将消息发送到服务。响应也被成功接收和解析。

问题

收到的响应表示500内部服务器错误,这是意外的。具体而言,自定义错误响应表示无法找到该服务。我确实认识到500内部服务器错误是一个非常普遍的问题,并且很难在没有日志的情况下进行调试,尽管我确实有一些猜测。

猜错是什么

一个猜测是端点/ soap操作不正确,无法找到服务。我觉得这是值得怀疑的,因为我们正在使用WSDL / soapUI中的确切凭据。

猜猜两个是SSL安全性没有得到正确处理,这在服务器的身份验证过程中导致内部服务器错误。这是我认为的问题,虽然我不确定。

一般情况。 。 。

有没有人看到这个问题?或者是否需要删除/添加任何内容?你知道任何其他指南可能比发送SOAP请求更好吗(我已经尝试了java的javax.xml.soap API,但是也没有用,但导致了同样的错误)?我已经尝试从soapUI生成代码,虽然我不知道如何处理生成的代码(除了使用ant构建)。我使用http://java.dzone.com/tips/generating-client-java-code来生成代码,虽然我不知道它是否是我正在寻找的。

备注

  • 我们正在调用一个我们无法访问日志的远程服务。

  • 来自xml文件的SOAP请求中的标头是空白的,这与soapUI不同,后者在应用传出WSS时为请求生成安全标头。消息的主体是等价的。即使包含java应用程序加载的SOAP请求的xml文件包含未过期的安全标头(在应用传出WSS后从soapUI复制),也会收到相同的无效响应。

  • 当我们将生成的soapUI消息从java(带有非过期安全标头)复制到soapUI时,会收到有效的响应。

  • 我们没有(我认为不需要)信任库。

任何人都可以看到可能出现的问题吗?是否有更多信息可以帮助解决问题(减去日志)?

谢谢!


代码:(路径,密码和网址是一般的)

public class SOAPController {

    static {
        org.apache.xml.security.Init.init();
    }

    final static String KEY_STORE_PATH = "PATH";
    final static String KEY_STORE_PASSWORD = "PASSWORD";

    public static void main(String[] args) throws Exception {
        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        InputStream keystoreInput = new FileInputStream(KEY_STORE_PATH);
        keystore.load(keystoreInput, KEY_STORE_PASSWORD.toCharArray());
        System.out.println("Keystore has " + keystore.size() + " keys");

        SchemeRegistry schemeRegistry = new SchemeRegistry();
        SSLSocketFactory lSchemeSocketFactory = new SSLSocketFactory(keystore,  KEY_STORE_PASSWORD);
        schemeRegistry.register(new Scheme("https", 443, lSchemeSocketFactory));

        final HttpParams httpParams = new BasicHttpParams();
        DefaultHttpClient lHttpClient = new DefaultHttpClient(new SingleClientConnManager(schemeRegistry), httpParams);

        String lUrl = "URL";

        String lXml = getStringFromDocument(new File("request1.xml"));
        System.out.println(lXml + "\n\n\n");

        HttpPost lMethod = new HttpPost(lUrl);
        HttpEntity lEntity = new StringEntity(lXml, "text/xml", "UTF-8");
        lMethod.setEntity(lEntity);
        lMethod.setHeader("SOAPAction", "soapaction");

        HttpResponse lHttpResponse = lHttpClient.execute(lMethod);

        System.out.println("Response status code: "
                + lHttpResponse.getStatusLine().getStatusCode());
        System.out.println("Response body: ");
        System.out.println(EntityUtils.toString(lHttpResponse.getEntity()));
    }

    public static String getStringFromDocument(File file)
    {
        try
        {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(file);        
           DOMSource domSource = new DOMSource(doc);
           StringWriter writer = new StringWriter();
           StreamResult result = new StreamResult(writer);
           TransformerFactory tf = TransformerFactory.newInstance();
           Transformer transformer = tf.newTransformer();
           transformer.transform(domSource, result);
           return writer.toString();
        }
        catch(Exception ex)
        {
           ex.printStackTrace();
           return null;
        }
    } 
}

的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.soap</groupId>
<artifactId>soap-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>soap-util</name>
<url>http://maven.apache.org</url>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient-cache</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.santuario</groupId>
        <artifactId>xmlsec</artifactId>
        <version>1.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom2</artifactId>
        <version>2.0.4</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.soap</groupId>
        <artifactId>javax.xml.soap-api</artifactId>
        <version>1.3.7</version>
    </dependency>
</dependencies>

 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-eclipse-plugin</artifactId>
            <configuration>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>true</downloadJavadocs>
            </configuration>
        </plugin>
    </plugins>
</build>

示例SOAP请求(注意空标题元素):

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <soap:Header/>
    <soap:Body>
        ... same as soapUI request ...
    </soap:Body>
</soap:Envelope>

1 个答案:

答案 0 :(得分:1)

解决:

所以我遗漏了很多标题数据。是什么让我意识到这一点是当我在soapUI中查看原始请求时,它有许多我没有的头文件。我刚刚添加了以下内容:

 lMethod.addHeader(headerName1, headerValue1);
 lMethod.addHeader(headerName2, headerValue2);
       ....