You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成部分XML签名(即SignedInfo标签内容)并封装为SOAP请求

类转换异常原因

你遇到的类转换错误是类加载冲突导致:JDK内置的XML DSIG实现和Apache Santuario库的DOMSignedInfo类全限定名高度相似,但属于不同的类加载源,完全不需要做这个强转操作,XMLSignatureFactory本身已经提供了官方序列化方法。

解决步骤

1. 准备空白DOM文档

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 必须开启命名空间感知
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().newDocument();

2. 直接序列化SignedInfo到DOM节点

XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
// 沿用你已有逻辑构造SignedInfo对象
SignedInfo si = fac.newSignedInfo(/* 你原有构造参数,包含已计算好的摘要、转换规则等 */);
// 直接调用marshal方法序列化,指定命名空间前缀为ds
fac.marshal(si, doc, "ds");
// 此时doc的根节点就是完整的<ds:SignedInfo>节点
Element signedInfoElement = doc.getDocumentElement();

3. 转换为XML字符串并封装为目标结构

将DOM节点转为字符串后,即可按需封装到SOAP信封的CDATA节点中:

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
// 可选配置:省略XML声明、开启格式化缩进
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
transformer.transform(new DOMSource(signedInfoElement), new StreamResult(sw));
String signedInfoXml = sw.toString();

后续你可以选择直接拼接字符串生成完整的SOAP结构,也可以用DOM生成完整SOAP信封,将signedInfoXml写入<signature>节点下的CDATA节点即可。

注意事项

  • 构造SignedInfo时指定的SignatureMethod算法需要和签名服务使用的算法保持一致
  • 序列化前需要确保所有Reference的DigestValue已经完成计算并填充
  • 如果需要外层包裹<ds:Signature>根节点,只需要提前在空白DOM中创建该节点作为父节点,调用marshal时传入该父节点即可

内容的提问来源于stack exchange,提问作者Val Bonn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 06:54:03