JAX-WS RI 不强制执行 XSD 限制
我目前正在使用 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
> 1000 或maxResults
<1)会通过验证过程而不被报告,并被注入到我的 JAXB 生成的 Java 结构中。尽管是xsd:positiveInteger
类型,但即使是负值也被认为是有效的! - 也不报告字符串长度约束违规(例如,
lastName
长度超过 25 个字符)。
换句话说,出现在
标记中的限制是正确执行的,但
元素在用于基于 JAX-WS 的上下文。
我编写了一个测试类来使用裸 JAXB(无 JAX-WS)检查我的 XSD 限制。因此,所有限制都得到正确执行。
这让我感觉 JAX-WS 使用 JAXB 时可能存在错误...当然,除非我做错了什么...
我在这里错过了一些基本的东西吗?!?
预先感谢您的帮助,
杰夫
I am currently developing a few Web services using the JAX-WS reference implementation (version 2.1.7). They are contract-based, that is, the WSDL and XSD files are not generated by wsgen.
This allows me to freely use XSD restrictions to strengthen validation of values passed to my services through SOAP messages. Here are two examples of such "restricted" XSD elements:
<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>
I added the @SchemaValidation
annotation to my service classes to enforce schema validation. However, JAX-WS does not enforce validation rules as expected. The behaviour is as follows:
- Missing mandatory elements are correctly reported (e.g., missing
maxResults
). - Invalid values (e.g., character data in an integer field) are correctly reported too.
- Interval restriction violations (e.g.,
maxResults
> 1000 ormaxResults
< 1) pass through the validation process without being reported and are injected into my JAXB-generated Java structures. Even negative values are considered valid despite thexsd:positiveInteger
type! - String length constraint violations (e.g.,
lastName
length over 25 characters) are not reported either.
In other words, restrictions that appear in <xsd:element>
tags are correctly enforced but <xsd:restriction>
elements seem to be totally ignored by JAXB when used in a JAX-WS-based context.
I wrote a test class to check my XSD restrictions using bare JAXB (no JAX-WS). As a result, all restrictions are correctly enforced.
This gives me the feeling that there might be a bug in the usage of JAXB by JAX-WS... unless there is something I am doing incorrectly, of course...
Am I missing something fundamental here?!?
Thanks in advance for any help,
Jeff
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我终于发现了问题所在...
为了让我的 Web 服务在 JUnit 上下文中工作,即通过
Endpoint.publish()
发布,我必须删除wsdlLocation
> 来自我的@WebService
注释的属性。如果不这样做,则传递给@WebService
注释的wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl"
会与传递给的 URL 值发生冲突>Endpoint.publish()
方法,http://127.0.0.1:9000/rpe-ws/SearchIndividuals
。阅读 Glen Mazza 的博客 (http://www.jroller.com/gmazza/entry/soap_xml_schema_validation),附加注释部分,我放回了
wsdlLocation
属性,所有限制都是现在已得到适当执行。换句话说,删除< 中声明的限制/code> 元素得到正确执行。但是,在
@WebService
注释中的wsdlLocation
不会阻止服务本身工作,但会阻止
元素中声明的限制仍然会正确执行。因此,我必须重新解决
wsdlLocation
兼容性问题,以使我的单元测试正常工作,但这比生产环境中的非工作验证要重要得多......以防万一。 .. 在非 Web 上下文中运行 Web 服务时,有人知道 WSDL 位置不兼容吗?
谢谢,
杰夫
I finally found what's wrong...
In order to get my Web services to work in a JUnit context, i.e. published through
Endpoint.publish()
, I had to remove thewsdlLocation
attribute from my@WebService
annotations. If I don't, thewsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl"
passed to the@WebService
annotation clashes with the URL value passed to theEndpoint.publish()
method,http://127.0.0.1:9000/rpe-ws/SearchIndividuals
.After reading Glen Mazza's Weblog (http://www.jroller.com/gmazza/entry/soap_xml_schema_validation), Additional Notes section, I put back the
wsdlLocation
attribute and all restrictions are now properly enforced.In other words, removing the
wsdlLocation
in a@WebService
annotation does not prevent the service itself from working, but prevents restrictions declared in<xsd:restrictions>
elements from being properly enforced. Restrictions declared in<xsd:element>
elements, however, are still correctly enforced.I am therefore getting back to having to solve that
wsdlLocation
compatibility problem to make my unit tests work properly, but this is way less critical than non-working validations in a production context...Just in case... Anyone has an idea about this WSDL location incompatibility when running a Web service in a non-Web context?
Thanks,
Jeff
噢,兄弟!...
为了覆盖 JUnit 测试的
wsdlLocation
,我创建了仅覆盖@WebService
注释的 Web 服务实现的派生。结果,我遇到了今天早上终于解决的同样问题(参考上面我的第一个答案)。经过大量测试后,我发现是标签。
@WebService
注释类的存在扩展了我的 Web 服务实现,导致 XSD 验证无法正确处理为了说明这种奇怪的行为,我们假设我有以下类:
其中
path/myWsdl.wsdl
正确定位了 WSDL。然后XSD验证工作正常,即我上面第一个答案的内容是完全有效的。我现在添加在基于 JUnit 的
Endpoint.publish()
调用中使用的以下类:除了
@WebService
注释之外,它不会覆盖任何内容。然后,XSD 验证会排除
标记,就像在指定wsdlLocation
属性之前所做的那样,尽管我仍然使用JeffWebServiceImpl
在我的非 JUnit 代码中实现!如果我注释掉 TestWebServiceImpl 中的注释,那么一切都会再次正常工作,当然,单元测试除外。换句话说,只要类路径中有某个类扩展了我的 Web 服务实现,最具体的类的 @WebService 注释就会覆盖所有其他类,无论我在常规中使用的实际类是什么Web 应用程序上下文。很奇怪,不是吗?!?
底线:我现在将禁用基于端点的单元测试。如果我(或阅读此线程的任何人)找到一种干净、非伪造的方式来集成生产和 JUnit 配置,我会考虑将它们放回我的 JUnit 测试套件中。
我希望这个帖子能帮助任何遇到同样问题的人比我更快地解决它......
杰夫
Oh brother!...
In order to override the
wsdlLocation
for my JUnit tests, I created derivations of my Web service implementations that override only the@WebService
annotation. As a result, I ran into the same problem I finally solved this morning (ref. my first answer above).After doing plenty of tests, I figured out that it's the presence of a
@WebService
-annotated class extending my Web service implementation that prevents XSD validation from properly handling<xsd:restriction>
tags.To illustrate this bizarre behaviour, let's suppose I have the following classes:
where
path/myWsdl.wsdl
correctly locates the WSDL. Then XSD validation works properly, i.e. the content of my first answer above is totally valid.I now add the following class that I use in my JUnit-based
Endpoint.publish()
calls:that overrides nothing but the
@WebService
annotation. Then XSD validation excludes<xsd:restriction>
tags as it used to do before specifying thewsdlLocation
attribute at all, despite the fact that I still use theJeffWebServiceImpl
implementation in my non-JUnit code! If I comment out the annotation inTestWebServiceImpl
, then everything works properly again, except for unit tests, of course.In other words, as soon as there is some class extending my Web service implementation in the classpath, the
@WebService
annotation of the most specific class overrides all others, regardless of the actual class I use in a regular Web application context. Weird, isn't it?!?Bottom line: I will disable Endpoint-based unit tests for now. If I (or anyone reading this thread) find a clean, non-bogus way to integrate both production and JUnit configurations, I will consider putting them back in my JUnit test suite.
I hope this thread will help anyone running into the same problem solve it faster than I did...
Jeff