我正在开发一些基于 Web 服务的应用程序,我对 Apache CXF 解码有疑问。在我们的项目中,我们使用 CXF 2.4.1 版本。
当某些 SOAP 请求不正确时(例如,某些字段是文本而不是数字),CXF 会抛出标准 SOAPFaultException 并且 SOAP 响应是使用标准字段构建的,例如:
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Unmarshalling Error: some field missing</faultstring>
</soap:Fault>
项目要求说,如果出现任何故障,系统需要以其他格式响应,例如:
<soap:body>
<ResponseState>
<ErrorCode>2732</ErrorCode>
<ErrorMessage>Unmarshalling Error: some field missing</ErrorMessage>
<ErrorDetails> some details </ErrorDetails>
<some other fields>
...
</ResponseState>
</soap:body>
所以问题是:我怎样才能以某种方式覆盖此错误处理并以我的格式而不是默认格式进行响应?
提前致谢。
附言我试图研究一些 ValidationEventHandler 原则,但它在 CXF 2.0 及更高版本中以其他方式工作。
最佳答案
好的,经过大量研究,我发现了一些 CXF 错误处理方法。
*。 ValidationEventHandler 使您可以抛出自己的异常而不是标准异常。但是您无法更改响应行为,也无法更改 SOAP 响应格式。
*。改变错误处理的另一种方法是创建您自己的拦截器。 CXF 工作流建立在拦截器链上。有 4 种类型的拦截器:inInterceptor、outInterceptor、inFaultInterceptor 和 outFaultInterceptor。
使用一些聪明的技巧,您可以通过创建自己的拦截器(将其添加到链中)来更改工作流,并从链中删除标准拦截器(如果您知道它的类名)。所以你实际上可以做任何你需要的事情。
但是就所有这些拦截器手动编码响应(xmlWriter.writeStartElement() 等)而言,为每个流程阶段编写您自己的拦截器可能是一个巨大的挑战。这可能是真正的大量工作。
不幸的是,我没有找到关于 CXF 拦截器的好引用。
另一件事 - 如果您需要返回常规响应而不是 SOAPFaultException,您可能需要其他信息,例如:返回此响应的实际服务、请求中传递的服务参数等。我没有在拦截器的可访问参数中找到此信息。而且,当然,通过这样做,您欺骗了将返回 OK 而不是真正异常的客户端代码。
*。使用所有参数作为文本设计 wsdl 可能不是很好的解决方案:
一个。如果 wsdl 中没有数据类型和验证规则,您的服务的消费者可能真的很困惑。
您需要“重新发明轮子”进行验证。我的意思是您需要编写自己的 validator ,这对于一些复杂的规则来说可能非常困难。同时,XSD 实现了所有这些验证并进行了良好测试。
最后关于我的情况:我们与需求经理讨论了它,并决定允许 CXF 在请求中违反 XML 模式要求时抛出它自己的标准异常。这是一个很好的解决方案,因为现在我们正在使用 XSD 验证的所有功能,而不是将时间浪费在复杂和无用的工作上。
非常感谢@ericacm 的回答。
关于java - 覆盖 CXF 错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10194748/
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee