我目前正在使用JAX-WS编写一组新的Web服务,但我在确定验证输入的最佳方法时遇到了困难.我可以在我的实现类中进行一些验证,但是一些输入错误会无声地失败.例如,数字元素中的字符数据将导致JAXB对象中的null整数.
这些是我遇到过的设计.
@SchemaValidation
我可以将这个注释添加到端点类中,JAX-WS将负责验证.这在tomcat本地工作,但有人担心它在某些服务器上不起作用.我的主要抱怨是我必须放弃控制错误在响应中的输出方式.
作为字符串的所有输入
我讨厌这种方法,但我已经看到其他所有输入被定义为字符串的Web服务.这将捕获数字元素中的字符数据的情况,因为我可以检查它调用我们的API,尽管你仍然会错过任何错误命名的xml元素.
我真的希望错误以与API错误相同的方式返回,而不是作为soap错误.有任何想法吗?我看过一些网站正在谈论用一种过滤器拦截请求.不知道这对于不同的操作的不同响应如何工作.
例如
<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>
Run Code Online (Sandbox Code Playgroud)
也许我问的太多了,但我想我会错过任何事情.TIA.
找到这篇文章解释了一种可能的方法.
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html
我让它在我的标准响应布局中返回解析错误消息.我只需要测试它将在客户机器上工作.(有人说他们遇到过@SchemaValidation的问题)
如果您坚持控制(在执行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
}
}
Run Code Online (Sandbox Code Playgroud)
A SOAPMessage将传递给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();
Run Code Online (Sandbox Code Playgroud)
提取SOAPBodyxml并Validator使用该validate()方法对其进行验证.
捕获验证周围的异常并构建自己的SOAP Fault:
//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);
Run Code Online (Sandbox Code Playgroud)
然后返回包含错误的SOAPMessage.
(不,我不喜欢SOAP Web服务)