11

我目前正在使用 JAX-WS 编写一组新的 Web 服务,但在确定验证输入的最佳方式时遇到了困难。我可以在我的实现类中进行一些验证,但一些输入错误会静默失败。例如,数字元素中的字符数据将导致 JAXB 对象中的 Integer 为空。

这些是我遇到的设计。

  1. @SchemaValidation
    我可以将此注释添加到端点类,JAX-WS 将负责验证。这在 tomcat 本地工作,但有人担心它不会在某些服务器上工作。我的主要抱怨是我必须放弃对错误在响应中的输出方式的控制。

  2. 所有输入都作为字符串
    我讨厌这种方法,但我见过其他所有输入都定义为字符串的 Web 服务。这将捕获数字元素中字符数据的情况,因为我可以在调用 API 的地方检查它,尽管您仍然会错过任何命名错误的 xml 元素。

我真的希望错误以与 API 错误相同的方式返回,而不是肥皂错误。有任何想法吗?我见过一些网站谈论使用一种过滤器来拦截请求。不过,不确定这将如何处理不同操作的不同响应。

例如

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <myOperationResponse>
         <return>
            <success>false</success>
            <errors>
               <error>
                  <code>UNIQUECODE</code>
                  <message>Message text</message>
               </error>
            </errors>
         </return>
      </myOperationResponse>
   </S:Body>
</S:Envelope>

也许我问得太多了,但我想我会看看我是否错过了什么。TIA。

4

4 回答 4

8

发现这篇文章解释了一种可能的方式。
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html

我让它在我的标准响应布局中返回解析错误消息。我只需要测试它是否可以在客户机器上运行。(有些人说他们遇到了@SchemaValidation 的问题)

于 2013-07-04T13:16:15.140 回答
7

如果您坚持控制(就像您在执行 Jax-WS 时通常需要放弃...),您可以实现针对 XSD 模式进行验证的 Provider 和 Validator。

XSD Schema 将负责验证输入(类型和潜在的枚举、模式匹配等......)

要将其实现javax.xml.ws.Provider为您的 SOAP 端点,请创建一个如下所示的类

@javax.xml.ws.ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
@javax.xml.ws.WebServiceProvider(
    wsdlLocation = "WEB-INF/wsdl/MyService.wsdl", 
    targetNamespace = "urn-com-acme-webservice", 
    serviceName = "ProcessPurchaseOrderService", 
    portName = "ProcessPurchaseOrderPort"
)
public class ProcessPurchaseOrder implements Provider<SOAPMessage> {


            @override
    public SOAPMessage invoke(final SOAPMessage request) {

                //see below     
    }
}

ASOAPMessage将被传递给invoke期望返回有效响应或包装在 SOAPMessage 中的 SOAPFault 的方法;

要再次验证 XSD,请使用javax.xml.validator

    URL url = this.getClass().getResource(xsdSchemaLocation);

    String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
    SchemaFactory factory = SchemaFactory.newInstance(language);
    Schema schema = factory.newSchema(url);

    validator = schema.newValidator();

提取SOAPBodyxml 并Validator使用该validate()方法对其进行验证。

围绕验证捕获异常并构建您自己的 SOAP 错误:

 //Build the SOAP Fault Response
 MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
 SOAPMessage response = factory.createMessage();

 SOAPFault fault = response.getSOAPBody().addFault();
 fault.setFaultString(myCustomErrorString);

 fault.addDetail().addChildElement("exception").addTextNode(myCustomErrorId);

然后返回包含故障的 SOAPMessage。

(不,我不喜欢 SOAP Web 服务)

于 2013-07-04T12:03:15.830 回答
2

在您尝试实现的场景中,不会出现任何 SOAP 错误。验证逻辑(将成为最终处理请求的代码的一部分)必须确保处理所有验证场景。

我们曾经遇到过这样的场景,在第三方集成我们的 Web 服务时,无法从 SOAP 错误中解读出太多信息,我们就像您设想的那样创建了错误响应。我建议采用以下方法。

  • 编写自己的验证逻辑
  • 创建适当的对象结构。您已经拥有一个 XML 格式的文件。只需要客观化它。
  • 调用此验证逻辑并将输入对象传递给它。验证逻辑将验证所有输入并填充适当的响应对象 ( myOperationResponse)。
  • 在验证方法返回时,检查状态或错误对象。如果有错误,则返回响应对象或继续进一步处理请求,然后返回成功响应。
于 2013-07-04T12:38:26.980 回答
0

我不确定我是否理解你的正确,但这可能对你有帮助:

http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html

于 2013-07-04T11:38:35.453 回答