JAX-WS RI 不强制执行 XSD 限制

发布于 2024-12-10 03:04:05 字数 1506 浏览 9 评论 0原文

我目前正在使用 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 or maxResults < 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 the xsd: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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴我老 2024-12-17 03:04:05

我终于发现了问题所在...

为了让我的 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属性,所有限制都是现在已得到适当执行。

换句话说,删除 @WebService 注释中的 wsdlLocation 不会阻止服务本身工作,但会阻止 < 中声明的限制/code> 元素得到正确执行。但是,在 元素中声明的限制仍然会正确执行。

因此,我必须重新解决 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 the wsdlLocation attribute from my @WebService annotations. If I don't, the wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl" passed to the @WebService annotation clashes with the URL value passed to the Endpoint.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

泪眸﹌ 2024-12-17 03:04:05

噢,兄弟!...

为了覆盖 JUnit 测试的 wsdlLocation,我创建了仅覆盖 @WebService 注释的 Web 服务实现的派生。结果,我遇到了今天早上终于解决的同样问题(参考上面我的第一个答案)。

经过大量测试后,我发现是 @WebService 注释类的存在扩展了我的 Web 服务实现,导致 XSD 验证无法正确处理 标签。

为了说明这种奇怪的行为,我们假设我有以下类:

@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 验证会排除 标记,就像在指定 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:

@WebService(...)
public interface JeffWebService {...}

@WebService(..., wsdlLocation = "path/myWsdl.wsdl", ...)
public class JeffWebServiceImpl implements JeffWebService {...}

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:

@WebService(..., wsdlLocation = "alternatePath/myWsdl.wsdl", ...)
public class TestWebServiceImpl extends JeffWebServiceImpl {}

that overrides nothing but the @WebService annotation. Then XSD validation excludes <xsd:restriction> tags as it used to do before specifying the wsdlLocation attribute at all, despite the fact that I still use the JeffWebServiceImpl implementation in my non-JUnit code! If I comment out the annotation in TestWebServiceImpl, 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文