Spring-ws 如何在请求正文中向 soap 操作添加属性
Spring-ws how to add an attribute to soap action in request body
我正在使用 Spring-WS 来使用以下 wsdl:
https://pz.gov.pl/pz-services/SignatureVerification?wsdl
我生成了 java 类 来像本教程中那样执行此操作:https://spring.io/guides/gs/consuming-web-service/
此 wsdl 文件的文档指定请求必须具有属性 callId 和 requestTimestamp 设置,就像在以下示例中一样:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tpus="http://verification.zp.epuap.gov.pl">
<soapenv:Header/>
<soapenv:Body>
<tpus:verifySignature callId="6347177294896046332" requestTimestamp="2014-06-30T12:01:30.048+02:00">
<tpus:doc>PD94bWwgdmVyc2E+</tpus:doc>
<tpus:attachments>
<tpus:Attachment>
<tpus:content>PD94bWwgdmVyc2+</tpus:content>
<tpus:name>podpis.xml</tpus:name>
</tpus:Attachment>
</tpus:attachments>
</tpus:verifySignature>
</soapenv:Body>
</soapenv:Envelope>
我的请求是这样的:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-82BA5532C">
<ns3:verifySignature
xmlns:ns3="http://verification.zp.epuap.gov.pl"
xmlns="">
<doc>PD94bWwgdmVyc2E+</doc>
<attachments>
<Attachment>
<content>PD94bWwgdmVyc2+</content>
<name>podpis.xml</name>
</Attachment>
</attachments>
</ns3:verifySignature>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
如您所见,我缺少 callId 和 requestTimestamp 属性。如果我发送请求的代码如下所示,我该如何添加它们?
public class TrustedProfileValidator extends WebServiceGatewaySupport {
private static final Logger tpLogger = Logger.getLogger(TrustedProfileValidator.class);
/**
* Trusted profile validator constructor
*/
public TrustedProfileValidator() {
tpLogger.info("Trusted profile validator service.");
}
public VerifySignatureResponse validate(byte[] documentInByte64, ArrayOfAttachment arrayOfAttachments) {
tpLogger.info("Checking trusted profile validation");
VerifySignature request = new VerifySignature();
request.setDoc(documentInByte64);
request.setAttachments(arrayOfAttachments);
return (VerifySignatureResponse) getWebServiceTemplate().marshalSendAndReceive(
"https://int.pz.gov.pl/pz-services/SignatureVerification", request,
new SoapActionCallback("verifySignature"));
}
}
这似乎有点奇怪,因为您提供的样本没有考虑肥皂作用;但正如我在示例中看到的那样,肥皂主体中添加了一些参数,这些参数未映射到 WS 架构中
在任何情况下,如果文档说明 soap 操作字符串必须具有这些参数,您仍然可以使用您使用过的参数,但您必须将属性传递给 SoapActionCallback:
例如,您可以执行以下操作
wsTemplate.marshalSendAndReceive("wsUri", youRequestObj, new SoapActionCallback("verifySignature callId=\""+callId+"\" requestTimestamp=\""+requestTimestamp+"\""));
这样springws会通过添加2个属性来编写soap动作
但我假设是要修改的皂体内容;所以在这种情况下你可以使用:
- org.springframework.ws.client.core.WebServiceTemplate
- WebServiceTemplate 的 sendSourceAndReceive 方法
- 您的自定义 SourceExtractor
例如,您可以使用这样的 XML 模板(通过使用速度完成)并调用 "requestTemplate.vm"
<?xml version="1.0" encoding="UTF-8" ?>
<tpus:verifySignature callId="${callId}" requestTimestamp="${timeStamp}" xmlns:tpus="http://verification.zp.epuap.gov.pl">
<tpus:doc>${doc}</tpus:doc>
<tpus:attachments>
<tpus:Attachment>
<tpus:content>${docContent}</tpus:content>
<tpus:name>${docName}</tpus:name>
</tpus:Attachment>
</tpus:attachments>
</tpus:verifySignature>
然后在你的代码中你可以这样做:
Map<String, Object> params = new HashMap<String, Object>(5);
params.put("callId", "myCallId");
params.put("timeStamp", "thetimeStamp");
params.put("doc", "theDoc");
params.put("docName", "theDocName");
params.put("docContent", "theDocContent");
String xmlRequest = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "requestTemplate.vm", "UTF-8", params).replaceAll("[\n\r]", "");
StreamSource requestMessage = new StreamSource(new StringReader(xmlRequest));
wsTemplate.sendSourceAndReceive("wsUrl", requestMessage,new new SoapActionCallback("verifySignature"),new CustomSourceExtractor());
您可以在 CustomSourceExtractor 中读取 SOAP 响应
我做了这样的事情
public class VieSourceExtractor implements SourceExtractor<YourObj>
{
@Override
public List<YourObj> extractData(Source src) throws IOException, TransformerException
{
XMLStreamReader reader = null;
try
{
reader = StaxUtils.getXMLStreamReader(src);
//read the xml and create your obj
return yourResult;
}
catch (Exception e)
{
throw new TransformerException(e);
}
finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (XMLStreamException e)
{
logger.error("Error " + e.getMessage(), e);
}
}
}
}
}
希望对您有所帮助
安杰洛
我正在使用 Spring-WS 来使用以下 wsdl: https://pz.gov.pl/pz-services/SignatureVerification?wsdl 我生成了 java 类 来像本教程中那样执行此操作:https://spring.io/guides/gs/consuming-web-service/
此 wsdl 文件的文档指定请求必须具有属性 callId 和 requestTimestamp 设置,就像在以下示例中一样:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tpus="http://verification.zp.epuap.gov.pl">
<soapenv:Header/>
<soapenv:Body>
<tpus:verifySignature callId="6347177294896046332" requestTimestamp="2014-06-30T12:01:30.048+02:00">
<tpus:doc>PD94bWwgdmVyc2E+</tpus:doc>
<tpus:attachments>
<tpus:Attachment>
<tpus:content>PD94bWwgdmVyc2+</tpus:content>
<tpus:name>podpis.xml</tpus:name>
</tpus:Attachment>
</tpus:attachments>
</tpus:verifySignature>
</soapenv:Body>
</soapenv:Envelope>
我的请求是这样的:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-82BA5532C">
<ns3:verifySignature
xmlns:ns3="http://verification.zp.epuap.gov.pl"
xmlns="">
<doc>PD94bWwgdmVyc2E+</doc>
<attachments>
<Attachment>
<content>PD94bWwgdmVyc2+</content>
<name>podpis.xml</name>
</Attachment>
</attachments>
</ns3:verifySignature>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
如您所见,我缺少 callId 和 requestTimestamp 属性。如果我发送请求的代码如下所示,我该如何添加它们?
public class TrustedProfileValidator extends WebServiceGatewaySupport {
private static final Logger tpLogger = Logger.getLogger(TrustedProfileValidator.class);
/**
* Trusted profile validator constructor
*/
public TrustedProfileValidator() {
tpLogger.info("Trusted profile validator service.");
}
public VerifySignatureResponse validate(byte[] documentInByte64, ArrayOfAttachment arrayOfAttachments) {
tpLogger.info("Checking trusted profile validation");
VerifySignature request = new VerifySignature();
request.setDoc(documentInByte64);
request.setAttachments(arrayOfAttachments);
return (VerifySignatureResponse) getWebServiceTemplate().marshalSendAndReceive(
"https://int.pz.gov.pl/pz-services/SignatureVerification", request,
new SoapActionCallback("verifySignature"));
}
}
这似乎有点奇怪,因为您提供的样本没有考虑肥皂作用;但正如我在示例中看到的那样,肥皂主体中添加了一些参数,这些参数未映射到 WS 架构中
在任何情况下,如果文档说明 soap 操作字符串必须具有这些参数,您仍然可以使用您使用过的参数,但您必须将属性传递给 SoapActionCallback: 例如,您可以执行以下操作
wsTemplate.marshalSendAndReceive("wsUri", youRequestObj, new SoapActionCallback("verifySignature callId=\""+callId+"\" requestTimestamp=\""+requestTimestamp+"\""));
这样springws会通过添加2个属性来编写soap动作
但我假设是要修改的皂体内容;所以在这种情况下你可以使用:
- org.springframework.ws.client.core.WebServiceTemplate
- WebServiceTemplate 的 sendSourceAndReceive 方法
- 您的自定义 SourceExtractor
例如,您可以使用这样的 XML 模板(通过使用速度完成)并调用 "requestTemplate.vm"
<?xml version="1.0" encoding="UTF-8" ?>
<tpus:verifySignature callId="${callId}" requestTimestamp="${timeStamp}" xmlns:tpus="http://verification.zp.epuap.gov.pl">
<tpus:doc>${doc}</tpus:doc>
<tpus:attachments>
<tpus:Attachment>
<tpus:content>${docContent}</tpus:content>
<tpus:name>${docName}</tpus:name>
</tpus:Attachment>
</tpus:attachments>
</tpus:verifySignature>
然后在你的代码中你可以这样做:
Map<String, Object> params = new HashMap<String, Object>(5);
params.put("callId", "myCallId");
params.put("timeStamp", "thetimeStamp");
params.put("doc", "theDoc");
params.put("docName", "theDocName");
params.put("docContent", "theDocContent");
String xmlRequest = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "requestTemplate.vm", "UTF-8", params).replaceAll("[\n\r]", "");
StreamSource requestMessage = new StreamSource(new StringReader(xmlRequest));
wsTemplate.sendSourceAndReceive("wsUrl", requestMessage,new new SoapActionCallback("verifySignature"),new CustomSourceExtractor());
您可以在 CustomSourceExtractor 中读取 SOAP 响应
我做了这样的事情
public class VieSourceExtractor implements SourceExtractor<YourObj>
{
@Override
public List<YourObj> extractData(Source src) throws IOException, TransformerException
{
XMLStreamReader reader = null;
try
{
reader = StaxUtils.getXMLStreamReader(src);
//read the xml and create your obj
return yourResult;
}
catch (Exception e)
{
throw new TransformerException(e);
}
finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (XMLStreamException e)
{
logger.error("Error " + e.getMessage(), e);
}
}
}
}
}
希望对您有所帮助
安杰洛