发送SOAP消息到Java和WS安全服务:内部服务器错误
我们的团队通过soapUI向远程服务发送请求并收集响应。为了实现这个过程的自动化,我制作了一个简单的Java应用程序,由以下教程指导。发送SOAP消息到Java和WS安全服务:内部服务器错误
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热曲EST(注意空的头元素):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
... same as soapUI request ...
</soap:Body>
</soap:Envelope>
解决:
所以我留下了很多头数据。是什么让我意识到这是当我看到soapUI中的原始请求时,它有许多我没有的标题。我只是增加了以下内容:
lMethod.addHeader(headerName1, headerValue1);
lMethod.addHeader(headerName2, headerValue2);
....