【问题标题】:Spring-ws how to add an attribute to soap action in request bodySpring-ws如何在请求正文中为soap动作添加属性
【发布时间】:2016-11-10 15:59:27
【问题描述】:

我正在使用 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"));
}

}

【问题讨论】:

  • 嗯,我想有什么问题。在您提供的 WSDL 中,我看不到有关 reqGetTpUserObjectsInfo、callId 和 requestTimestamp 的信息;所以或你正在阅读另一个文档,或者你发布了不同的 WSDL
  • 因为示例(在文档中)是针对另一种方法的,所以 callId 和 requestTimestamp 是必须为每个请求设置的参数。所以我的请求也应该有这些参数。我将编辑示例,因此不再有误解
  • 奇怪的是,在 WSDL 定义中没有引用属性 callId 和 requestTimestamp 以及对象 reqGetTpUserObjectsInfo;所以在我看来,或者有一些错误(可能是另一个 WSDL)或者在文档中有一些与安全性相关的东西(例如 ws-security);在 ws-security 的情况下,有一些参数与您编写的参数类似,但它们是在soap header 中编写的;您也可以通过使用 SOAP-UI 测试 WS 来获得与 spring-ws 相同的结果
  • 我使用 ws-security 对消息进行签名,但它指定 Soap 操作必须具有这些参数。有没有办法在发送肥皂消息之前对其进行编辑?像拦截器一样?

标签: java spring soap wsdl spring-ws


【解决方案1】:

这似乎有点奇怪,因为您提供的示例没有考虑肥皂动作;但正如我在示例中看到的那样,肥皂体中添加了一些参数,这些参数未映射到 WS 架构中

在任何情况下,如果文档说肥皂操作字符串必须具有这些参数,您仍然可以使用您使用的参数,但您必须将属性传递给 SoapActionCallback: 例如,您可以执行以下操作

wsTemplate.marshalSendAndReceive("wsUri", youRequestObj, new SoapActionCallback("verifySignature callId=\""+callId+"\"  requestTimestamp=\""+requestTimestamp+"\""));

这样spring ws会通过添加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);
}
}
}
}
}

希望对你有帮助

安杰洛

【讨论】:

  • 不幸的是,将 "verifySignature callId=\""+callId+"\" requestTimestamp=\""+requestTimestamp+"\"" 写入 SoapActionCallback 返回:The given SOAPAction verifySignature callId="6347177294896046332" requestTimestamp="2016-11-14T10:14:24.524+01:00 does not match an operation。我检查了发送的请求,xml没有被修改。所以不可能像那样修改肥皂动作。我会试试你的其他建议:)
  • 我很确定这是要更改的 XML 正文,就像我告诉你的那样……让我知道……现在我很好奇;顺便说一句...我写的VM模板必须改进...只是一个示例
  • 我最终修改了java spring生成的类,结果这些参数在文档中,但是文档已经过时了...谢谢您的帮助
猜你喜欢
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 2014-10-14
  • 2021-10-08
相关资源
最近更新 更多