我目前正在使用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>
也许我问的太多了,但我想我会看到我错过了什么。 TIA。
如果您坚持控制(在执行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
}
}
一个 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();
提取 SOAPBody
xml并对其进行验证 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);
然后返回包含错误的SOAPMessage。
(不,我不喜欢SOAP Web服务)
如果您坚持控制(在执行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
}
}
一个 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();
提取 SOAPBody
xml并对其进行验证 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);
然后返回包含错误的SOAPMessage。
(不,我不喜欢SOAP Web服务)
在你想要实现的场景中,那里 不会是任何SOAP错误。验证逻辑(这将是最终处理请求的代码的一部分 ),必须确保处理所有验证方案。
我们遇到过这样的情况:第三方集成我们的Web服务无法解释SOAP故障,我们通过创建错误响应就像您构思的那样。我建议采用以下方法。
- 编写自己的验证逻辑
- 创建适当的对象结构。您已经有一种XML格式。只需要客观化它。
- 调用此验证逻辑并将输入对象传递给它。验证逻辑将验证所有输入并填充适当的响应对象(
myOperationResponse
)。
- 返回验证方法时,检查状态或错误对象。如果有错误,则返回响应对象或继续处理请求,然后返回成功响应。