我目前正在使用JAX-WS参考实现(版本2.1.7)开发一些Web服务。它们是基于契约的,也就是说,WSDL和XSD文件不是由wsgen生成的。
这允许我自由使用XSD限制来加强对通过SOAP消息传递给我的服务的值的验证。以下是此类“受限制”XSD元素的两个示例:
<xsd:element name="maxResults" minOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive value="1000"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="lastName" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="1"/>
<xsd:maxLength value="25"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
我将@SchemaValidation
注释添加到我的服务类中以强制执行模式验证。但是,JAX-WS不会按预期强制执行验证规则。行为如下:
maxResults
)。maxResults
&gt; 1000或maxResults
&lt; 1)在没有报告的情况下通过验证过程,并被注入到我的JAXB生成的Java结构中。即使是xsd:positiveInteger
类型,即使负值也被视为有效!lastName
长度超过25个字符)。换句话说,<xsd:element>
标记中出现的限制被正确实施,但在基于JAX-WS的上下文中使用时,JAXB似乎完全忽略了<xsd:restriction>
个元素。
我编写了一个测试类,使用裸JAXB(无JAX-WS)来检查我的XSD限制。因此,所有限制都得到了正确执行。
这让我觉得JAX-WS在使用JAXB时可能存在错误...除非我做错了什么,当然......
我错过了一些基本的东西吗?!?
提前感谢您的帮助,
杰夫
答案 0 :(得分:2)
我终于找到了什么错误......
为了让我的Web服务在JUnit上下文中工作,即通过Endpoint.publish()
发布,我必须从wsdlLocation
注释中删除@WebService
属性。如果不这样做,则传递给wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl"
注释的@WebService
会与传递给Endpoint.publish()
方法{1}}的网址值冲突。
在阅读Glen Mazza的博客(http://www.jroller.com/gmazza/entry/soap_xml_schema_validation),附加说明部分后,我放回了http://127.0.0.1:9000/rpe-ws/SearchIndividuals
属性,现在所有限制都已正确执行。
换句话说,删除wsdlLocation
注释中的wsdlLocation
并不会阻止服务本身工作,但会阻止@WebService
元素中声明的限制被正确实施。但是,<xsd:restrictions>
元素中声明的限制仍然可以正确执行。
因此,我回到必须解决<xsd:element>
兼容性问题以使我的单元测试正常工作,但这比生产环境中的非工作验证更不重要...
以防万一...在非Web上下文中运行Web服务时,任何人都知道这个WSDL位置不兼容吗?
谢谢,
杰夫
答案 1 :(得分:0)
哦,兄弟!...
为了覆盖我的JUnit测试的wsdlLocation
,我创建了仅覆盖@WebService
注释的Web服务实现的派生。结果,我遇到了今天早上我终于解决的同样问题(参见我上面的第一个答案)。
经过大量测试后,我发现存在一个@WebService
- 带注释的类,扩展了我的Web服务实现,阻止了XSD验证正确处理<xsd:restriction>
标记。
为了说明这种奇怪的行为,我们假设我有以下类:
@WebService(...)
public interface JeffWebService {...}
@WebService(..., wsdlLocation = "path/myWsdl.wsdl", ...)
public class JeffWebServiceImpl implements JeffWebService {...}
其中path/myWsdl.wsdl
正确定位WSDL。然后XSD验证工作正常,即我上面第一个答案的内容完全有效。
我现在在基于JUnit的Endpoint.publish()
调用中添加以下类:
@WebService(..., wsdlLocation = "alternatePath/myWsdl.wsdl", ...)
public class TestWebServiceImpl extends JeffWebServiceImpl {}
除了@WebService
注释之外什么都不会覆盖。然后,在完全指定<xsd:restriction>
属性之前,XSD验证会像以前一样排除wsdlLocation
标记,尽管事实上我仍在我的非JUnit代码中使用JeffWebServiceImpl
实现!如果我在TestWebServiceImpl
中注释掉注释,那么除了单元测试之外,一切都能正常工作。
换句话说,只要有一些类在类路径中扩展我的Web服务实现,最具体的类的@WebService
注释会覆盖所有其他类,而不管我在常规Web中使用的实际类应用背景。很奇怪,不是吗?!?
底线:我现在将禁用基于端点的单元测试。如果我(或任何阅读此线程的人)找到一种干净的,非虚假的方式来集成生产和JUnit配置,我会考虑将它们放回我的JUnit测试套件中。
我希望这个帖子可以帮助遇到同样问题的人解决问题的速度比我做得快......
杰夫