【发布时间】:2017-06-07 19:28:21
【问题描述】:
我们目前正在开发一个包含第 3 方 XSD 的网络服务。此第 3 方 XSD 包含数字签名(导入 http://www.w3.org/2000/09/xmldsig# XSD)。
该架构有 2 个主要功能:
- 我们的 Web 服务根据第 3 方 XSD 合同接受消息
- 我们将其中一些消息转发给另一个(也是第 3 方) 通过小客户端提供网络服务
1) 完美运行,这里没有涉及签名的问题。
2) 是奇数。只要签名元素
<xs:element ref="sig:Signature" minOccurs="0" maxOccurs="1"/>
存在,软件不会启动,而是崩溃并显示以下错误消息:
引起:org.springframework.beans.BeanInstantiationException: 无法实例化 [net.eucaris.services.GenericServiceSoap]: 工厂方法“genericServiceSoap”抛出异常;嵌套异常 是 java.lang.IllegalArgumentException:无法解析参数号: ''{0}'' 在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) [spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE] 在 org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) [spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE] ... 38 更多 原因: java.lang.IllegalArgumentException:无法解析参数号: ''{0}'' 在 java.text.MessageFormat.makeFormat(MessageFormat.java:1429) [rt.jar:1.8.0_131] 在 java.text.MessageFormat.applyPattern(MessageFormat.java:479) [rt.jar:1.8.0_131] 在 java.text.MessageFormat.(MessageFormat.java:362) [rt.jar:1.8.0_131] 在 java.text.MessageFormat.format(MessageFormat.java:840) [rt.jar:1.8.0_131] 在 com.sun.xml.bind.v2.model.impl.Messages.format(Messages.java:132) [jaxb-impl-2.2.11.jar:2.2.11]
我将其追溯到生成的文件,确切地说是端口类型接口:
@WebService(targetNamespace = "http://services.eucaris.net/", name = "GenericServiceSoap")
@XmlSeeAlso({org.w3._2000._09.xmldsig_.ObjectFactory.class, ObjectFactory.class})
public interface GenericServiceSoap {
...
只要这里引用了xmldsig-ObjectFactory,系统就会崩溃。一旦它出来,一切正常(嗯,直到有人发送签名,然后无法识别)。
深入挖掘(即调试)使我得到以下信息:
在这段代码中抛出了异常(java.text.MessageFormat,来自第 1415 行,jdk 1.8.131)
private void makeFormat(int position, int offsetNumber,
StringBuilder[] textSegments)
{
String[] segments = new String[textSegments.length];
for (int i = 0; i < textSegments.length; i++) {
StringBuilder oneseg = textSegments[i];
segments[i] = (oneseg != null) ? oneseg.toString() : "";
}
// get the argument number
int argumentNumber;
try {
argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized!
} catch (NumberFormatException e) {
throw new IllegalArgumentException("can't parse argument number: "
+ segments[SEG_INDEX], e);
}
方法参数为 73、0 和一个包含此数据的StringBuilder:
[Esist keine ObjectFactory mit @XmlElementDecl für das Element ', ''{0}'', null, null]
这表明,不知何故,在某个地方,这个 StringBuffer 被错误地填充了,因为该方法显然需要一个数字。 ''{0}'' 有点像占位符。考虑到消息的内容,应用程序本身会尝试引发错误或至少是警告。
更多信息:
我们使用 CXF 3.1.11 和 Spring 4.3.8。我们从 wsdl 和 xsd 文件生成代码。客户端是通过
创建的@Bean
public GenericServiceSoap genericServiceSoap() {
final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(http://example.com);
factory.setServiceClass(GenericServiceSoap.class);
factory.setInInterceptors(createInInterceptors());
factory.setOutInterceptors(createOutInterceptors());
return (GenericServiceSoap) factory.create();
}
签名生成这段代码,我觉得很好:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SignatureType", propOrder = {
"signedInfo",
"signatureValue",
"keyInfo",
"objects"
})
@XmlRootElement(name = "Signature")
public class Signature implements Serializable
{
private final static Long serialVersionUID = 5363422069410258353L;
@XmlElement(name = "SignedInfo", required = true)
@NotNull
protected SignedInfo signedInfo;
@XmlElement(name = "SignatureValue", required = true)
@NotNull
protected SignatureValue signatureValue;
@XmlElement(name = "KeyInfo")
protected KeyInfo keyInfo;
@XmlElement(name = "Object")
protected List<org.w3._2000._09.xmldsig_.Object> objects;
@XmlAttribute(name = "Id")
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlID
@XmlSchemaType(name = "ID")
@Pattern(regexp = "[\\i-[:]][\\c-[:]]*")
protected String id;
// getters/setters omitted
我只是不明白这是怎么发生的,或者为什么会发生。还是我在这里遇到了错误?
【问题讨论】:
标签: java cxf xml-signature