2011-10-13 33 views
3

我目前正在使用JAX-WS参考实现(版本2.1.7)开发一些Web服务。它们是基于合同的,也就是说,WSDL和XSD文件不是由wsgen生成的。JAX-WS RI不执行XSD限制

这使我可以自由使用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类型,甚至负值也被认为是有效的!
  • 不报告字符串长度约束违规(例如,长度超过25个字符的lastName)。

在出现在<xsd:element>标签换句话说,限制正确实施,但<xsd:restriction>元素似乎在基于JAX-WS的上下文中使用时,可以完全被忽略JAXB。

我写了一个测试类来检查我的XSD限制使用裸JAXB(没有JAX-WS)。结果,所有限制都被正确执行。

这给我的感觉,有可能是在JAXB通过JAX-WS的使用......一个bug,除非有什么我做的,当然不正确,...

我失去了一些基本的东西这里?!?

在此先感谢您的帮助,

杰夫

+0

有多种@SchemaValidation注解。一个为我工作的是com.sun.xml.ws.developer.SchemaValidation。我错误地使用com.sun.xml.internal.ws.developer.SchemaValidation,并没有工作。 –

回答

2

我终于找到什么是错的......

为了让我的Web服务在JUnit的环境中工作,即通过Endpoint.publish()公布,我必须从我的@WebService注释中删除wsdlLocation属性。如果我不知道,则wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl"传递给@WebService注释冲突,并将URL值传递给Endpoint.publish()方法http://127.0.0.1:9000/rpe-ws/SearchIndividuals

阅读格伦马萨的博客(http://www.jroller.com/gmazza/entry/soap_xml_schema_validation),其他注意事项节过后,我放回wsdlLocation属性和现在的所有限制都正确执行。

换句话说,在@WebService注释去掉wsdlLocation不会阻止该服务本身的工作,但防止<xsd:restrictions>元素宣布限制从被正确执行。然而,在<xsd:element>元素中声明的限制仍然正确执行。

因此,我又回到了不得不解决wsdlLocation兼容性问题,使我的单元测试正常工作,但是这是不是在生产方面不受工作验证的方式不太重要...

以防万一...在非Web环境中运行Web服务时,任何人都有关于此WSDL位置不兼容的想法?

感谢,

杰夫

0

哦兄弟!...

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

经过大量测试后,我发现它存在@WebService-annotated类,它扩展了我的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验证排除了<xsd:restriction>标记,因为它在完全指定wsdlLocation属性之前完全不用,尽管我仍然在非JUnit代码中使用JeffWebServiceImpl实现!如果我在TestWebServiceImpl中注释掉注释,那么除了单元测试外,一切都会正常工作。

换句话说,只要有一些类在类路径中扩展我的Web服务实现,最具体类的@WebService注释会覆盖所有其他类,而不管我在常规Web应用程序上下文中使用的实际类。奇怪,不是吗?!?

底线:我现在将禁用基于端点的单元测试。如果我(或者任何读这个线程的人)发现一种整合生产和JUnit配置的干净,非伪造的方式,我会考虑将它们放回到我的JUnit测试套件中。

我希望这个线程将帮助任何人遇到了同样的问题,解决这个问题比我快......

杰夫