覆盖CXF错误处理 [英] Override CXF error handling

查看:103
本文介绍了覆盖CXF错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一些基于Web服务的应用程序,我有一个关于Apache CXF解组的问题。在我们的项目中,我们使用CXF 2.4.1版本。



当某些SOAP请求不正确时(例如某些字段是文本而不是数字),CXF抛出标准SOAPFaultException,SOAP响应为使用以下标准字段构建:

 < soap:Fault> 
< faultcode> soap:Client< / faultcode>
< faultstring>解组错误:某些字段缺失< / faultstring>
< / soap:错误>

项目要求说如果出现任何故障,系统需要以其他格式响应,例如:

 < soap:body> 
< ResponseState>
< ErrorCode> 2732< / ErrorCode>
< ErrorMessage>解组错误:某些字段缺失< / ErrorMessage>
< ErrorDetails>一些细节< / ErrorDetails>
<其他一些字段>
...
< / ResponseState>
< / soap:body>

所以问题是:如何以某种方式覆盖此错误处理并以我的格式响应,而不是默认?



提前致谢。



PS我试图查看一些ValidationEventHandler主体,但它在CXF 2.0及更高版本中以其他方式工作。

解决方案

好的,所以经过大量的研究,我发现了一些CXF错误处理方法。



*。 ValidationEventHandler使您可以抛出自己的异常而不是标准异常。但是您无法更改响应行为,也无法更改SOAP响应格式。



*。另一种改变错误处理的方法是创建自己的拦截器。 CXF工作流程建立在拦截器链上。有4种类型的拦截器:inInterceptor,outInterceptor,inFaultInterceptor和outFaultInterceptor。



使用一些智能黑客,您可以通过创建自己的拦截器(将其添加到链)来更改工作流程,并从链中删除标准拦截器(如果您知道它的类名) 。所以你可以做任何你需要的事情。



但是,就所有这些拦截器手动编组响应(xmlWriter.writeStartElement()等)而言,为每个流程阶段编写自己的拦截器可能是一个很大的挑战。这可能是真正的大量工作。



不幸的是,我还没有找到关于CXF拦截器的好参考。



<另一件事 - 如果你需要返回常规响应而不是SOAPFaultException,你可能需要额外的信息,例如:返回此响应的实际服务,请求中传递的服务参数等。我没有在拦截器中的可访问参数中找到此信息。并且,当然,通过这样做,你欺骗客户端代码将返回OK而不是真正的异常。



*。用所有参数设计你的wsdl作为文本可能是非常不好的解决方案:



a。如果wsdl中没有数据类型和验证规则,那么您的服务的使用者可能会非常困惑。



b。你需要'重新发明轮子'进行验证。我的意思是你需要编写自己的验证器代码,这些验证器在一些复杂的规则下可能非常困难。同时XSD已经实现了所有这些验证并且经过了良好的测试。



最后关于我的情况:我们与需求经理讨论了它并决定允许CXF抛出它自己的如果请求中违反了XML架构要求,则为标准异常。这是一个很好的解决方案,因为现在我们正在使用XSD验证的所有功能,不要把时间浪费在复杂和无用的工作上。



非常感谢@ericacm的回答。


I am working on some web-services based application and I have a question about Apache CXF unmarshalling. In our project we use CXF 2.4.1 version.

When some SOAP request is incorrect (e.g. some field is text instead of numeric) CXF throws standard SOAPFaultException and SOAP response is built up with standard fields like:

<soap:Fault>
    <faultcode>soap:Client</faultcode>
    <faultstring>Unmarshalling Error: some field missing</faultstring>
</soap:Fault>

Project requirements says that in case of any fault system need to respond in other format, like:

<soap:body>
    <ResponseState>
        <ErrorCode>2732</ErrorCode>
        <ErrorMessage>Unmarshalling Error: some field missing</ErrorMessage>
        <ErrorDetails> some details </ErrorDetails>
        <some other fields>
        ...
    </ResponseState>
</soap:body>

So the question is: how can I override somehow this error handling and respond in my format, not default?

Thanks in advance.

P.S. I tried to look into some ValidationEventHandler principals, but it works in some other way in CXF 2.0 and higher.

解决方案

OK, So after lot of research I've found some ways of CXF error handling.

*. ValidationEventHandler gives you possibility to throw your own exception instead of standard one. BUT you can't change responding behavior and you can't change SOAP response format.

*. Another way to alter error handling is to create your own interceptor. CXF workflow is built on chain of interceptors. There's 4 type of interceptors: inInterceptor, outInterceptor, inFaultInterceptor and outFaultInterceptor.

Using some smart hacks you can change workflow through creating your own interceptor (with adding it to chain), and remove standard interceptor from chain (if you know it's class name). So you can actually do anything you need.

BUT as far as all these interceptors marshall response manually (xmlWriter.writeStartElement() etc) it could be a great challenge to write your own interceptors for each flow phase. It could be real huge bunch of work.

Unfortunately, I haven't found good reference about CXF interceptors.

Another thing - if you need to return regular response instead of SOAPFaultException you may need additional information like: actual service that return this response, service parameters passed in request etc. I haven't found this info in accessible parameters in interceptors. And, surely, by doing so you cheat client code that will return OK instead of real exception.

*. Designing your wsdl's with all params as text may be very not very good solution:

a. Consumer of your services may be really confused if no data types and validation rules in wsdl.

b. You'll need to 'reinvent the wheel' for validation. I mean that you'll need to code your own validator that could be very difficult with some complicated rules. At the same time XSD has all of this validations implemented and good tested.

And finally about my situation: we discussed it with requirement manager and decided to allow CXF throw it's own standard exceptions if XML schema requirements violated in request. It's good solution because now we are using all the power of XSD validation and don't waste our time on complicated and useless work.

Great thanks to @ericacm for answer.

这篇关于覆盖CXF错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆