I'm using Spring-WS to consume a following wsdl: https://pz.gov.pl/pz-services/SignatureVerification?wsdl I've generated java classes to do this just like in this tutorial: https://spring.io/guides/gs/consuming-web-service/
Documentation of this wsdl file specifies, that a request has to have an attributes callId, and requestTimestamp set just like in the following example:
<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>
My request looks like this:
<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>
So as you can see i lack the callId and requestTimestamp attributes. How i can add them if my code to send the request looks like this?
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"));
}
}
It seems little bit strange because the sample you provided doesn't reagard the soap-action; but as i can see in the sample there are some parameters added to the soap body and these parameters are not mapped in the WS schema
In any case if the documentation says that the soap action string must have these parameters you can still use what you used but you must pass the attributes to the SoapActionCallback: For example you can do the following
wsTemplate.marshalSendAndReceive("wsUri", youRequestObj, new SoapActionCallback("verifySignature callId=\""+callId+"\" requestTimestamp=\""+requestTimestamp+"\""));
In this way spring ws will write the soap action by adding the 2 attributes
But I assume that it's the soap-body content to be modified; so in this case you can use:
For example you can use a XML template like this (done by using velocity) and called "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>
then in your code you can do something like this:
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());
where CustomSourceExtractor is where you can read the SOAP response
I did something like this
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);
}
}
}
}
}
I hope this can help you
Angelo