我正在使用Apache CXF Web服务(使用JAX-WS,通过SOAP).服务本身很简单:接收请求,将请求插入数据库,并返回插入是否成功.我想依靠
XML验证来强制执行这个请求的一些约束.
所以,我的问题.如何将详细的验证错误返回给我的服务的客户端?我通过配置我的端点,在服务器端进行了验证.
<jaxws:endpoint id="someEndpoint" implementor="#someImpl" address="/impl"> <jaxws:properties> <!-- This entry should- ideally- enable JAXB validation on the server-side of our web service. --> <entry key="schema-validation-enabled" value="true" /> </jaxws:properties> </jaxws:endpoint>
我已经在服务器上使用拦截器(例如BareInInterceptor)进行了探索,并以某种方式捕获SAXParseExceptions来包装它们并将它们发送到客户端.这种方法似乎有点复杂,但是如果XML无效,我需要以某种方式给客户端一个行号.我应该与拦截器一起揭露例外吗?
我对这个技术栈不是很有经验,只是进入网络服务 – 你们可以给我的任何指针都将非常感激.
解决方法
您可以使用自定义ValidationEventHandler来覆盖验证错误消息,插入行号:
package example; import javax.xml.bind.ValidationEvent; import javax.xml.bind.helpers.DefaultValidationEventHandler; public class MyValidationEventHandler extends DefaultValidationEventHandler { @Override public boolean handleEvent(ValidationEvent event) { if (event.getSeverity() == ValidationEvent.WARNING) { return super.handleEvent(event); } else { throw new RuntimeException(event.getMessage() + " [line:"+event.getLocator().getLineNumber()+"]"); } } }
如果您将端点配置为使用此处理程序:
<jaxws:endpoint id="someEndpoint" implementor="#someImpl" address="/impl"> <jaxws:properties> <entry key="schema-validation-enabled" value="true" /> <entry key="jaxb-validation-event-handler"> <bean class="example.MyValidationEventHandler" /> </entry> </jaxws:properties> </jaxws:endpoint>
那么你会得到如下的SOAP错误:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <soap:Fault> <faultcode>soap:Client</faultcode> <faultstring>Unmarshalling Error: Not a number: xyz [line: 6]</faultstring> </soap:Fault> </soap:Body> </soap:Envelope>
jaxb-validation-event-handler属性最近才被添加到CXF,所以你需要确保使用最新版本 – 我用2.2.5测试了这个.