axis2中关于AxisFault的说明

2024-04-29 23:18
文章标签 说明 axis2 axisfault

本文主要是介绍axis2中关于AxisFault的说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一般说来,不可避免的Web Service的服务中也会出现异常,举个简单的例子,一个服务接受一个SOAP请求消息,获取有效负载后,进行一个数据库更新操作,而在更新操作过程中发生了SQLException,这个时候就需要告诉客户端(调用Web Service)出现异常了,Axis2将异常封装成为一个AxisFault进行抛出。任何类型的异常Axis2都会对其进行封装,而不管该异常是运行时异常,还是用户自定义异常。
下面是对AxisFault API的一点介绍:
public class AxisFault extends RemoteException
An exception which maps cleanly to a SOAP fault. This is a base class for exceptions which are mapped to faults.
See Also:
SOAP1.2 specification, SOAP1.1 Faults
SOAP faults contain
1.     A fault string
2.     A fault code
3.      A fault actor
4.      Fault details; an xml tree of fault specific elements
(其中红色的部分为一个AxisFault构造时所必须的部分)
As SOAP1.2 faults are a superset of SOAP1.1 faults, this type holds soap1.2 fault information. When a SOAP1.1 fault is created, spurious information can be discarded. Mapping
SOAP1.2              SOAP1.1
node                 faultactor
reason(0).text       faultstring
faultcode.value      faultcode
faultcode.subcode    (discarded)
detail               detail
role                 (discarded)
构造函数之一为:
AxisFault (org.apache.axiom.soap.SOAPFaultCode soapFaultCode, org.apache.axiom.soap.SOAPFaultReason soapFaultReason, org.apache.axiom.soap.SOAPFaultNode soapFaultNode, org.apache.axiom.soap.SOAPFaultRole soapFaultRole, org.apache.axiom.soap.SOAPFaultDetail soapFaultDetail)
由于SOAP 1.1的SOAPFault和SOAP 1.2的SOAPFault的结构不相同,从而导致了如果以1.2的方式构造的SOAPFault不能够被1.1版本的SOAPFault所理解,从而导致异常,异常的内容经常为如下消息:
org.apache.axiom.soap.SOAPProcessingException: Expecting SOAP 1.1 implementation
of SOAP Fault Code. But received some other implementation
一般情况下,SOAPFault是通过SOAPFactory这个工厂类构造的,而SOAP11Factory和SOAP12Factory均继承SOAPFactory,从而对应与两个不同的SOAP协议版本。
可以将SOAP1.1的SOAPFault与SOAP1.2的SOAPFault进行转换,但是比较麻烦。
下面以一个实际的例子来说明有关SOAPFault的一些内容:
1.      建立工程TestFault,如下图所示目录结构:
其中类库使用的是从http://ws.apache.org/axis2下载的最新版本的axis2软件中的类库(笔者写这篇文章时的最新axis2版本为1.1.1)。下载后解压缩,将解压缩后的目录中的lib文件夹下所有的jar文件拷贝到${eclipse.home}/workspace/TestFault/src下,目录结构可能与此不同,只需要将这些jar文件加入到TestFault工程的构建路径中即可。
编写服务器端和客户端的类:
FaultService.java
package l.z.z;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axiom.soap.SOAPFaultText;
import org.apache.axiom.soap.SOAPFaultValue;
import org.apache.axis2.AxisFault;
public class FaultService {
public OMElement testFault(OMElement soap) throws AxisFault {
if (soap.getLocalName().equals("Satan")) {
throw getAxisFault("Satan");
}
throw getAxisFault("God");
}
public AxisFault getAxisFault(String message) {
SOAPFactory factory = OMAbstractFactory.getSOAP12Factory();
SOAPEnvelope envelope = factory.createSOAPEnvelope();
SOAPBody body = factory.createSOAPBody(envelope);
SOAPFault soapFault = factory.createSOAPFault(body);
SOAPFaultCode faultCode = factory.createSOAPFaultCode(soapFault);
SOAPFaultReason faultReason =
factory.createSOAPFaultReason(soapFault);
SOAPFaultValue faultValue = factory.createSOAPFaultValue(faultCode);
SOAPFaultText reasonText =
factory.createSOAPFaultText(faultReason);
QName value =
new QName(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI,
SOAP12Constants.SOAP_FAULT_VALUE_SENDER,
SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX);
faultValue.setText(value);
reasonText.setText(message);
AxisFault axisFault = new AxisFault(soapFault.getCode(), soapFault
.getReason(), null, null, null);
return axisFault;
}
}
TestFaultService.java
package l.z.z.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
public class TestFaultService {
private static EndpointReference targetEPR = new EndpointReference(
"http://localhost/axis2/services/FaultService");
public static void main(String[] args) throws FileNotFoundException,
FactoryConfigurationError, XMLStreamException {
OMElement requestSoapMessage =
getSoapRequestMessage("sample/Satan.xml");
Options options = new Options();
options.setAction("urn:testFault");
options.setTo(targetEPR);
ServiceClient sender = null;
try {
sender = new ServiceClient();
sender.setOptions(options);
sender.sendReceive(requestSoapMessage);
} catch (AxisFault e) {
System.out.println(e.getMessage());
}
}
public static OMElement getSoapRequestMessage(String filePath)
throws FileNotFoundException, XMLStreamException,
FactoryConfigurationError {
XMLStreamReader reader = XMLInputFactory.newInstance()
.createXMLStreamReader(new FileInputStream(filePath));
StAXOMBuilder builder = new StAXOMBuilder(reader);
OMElement requestMessage = builder.getDocumentElement();
return requestMessage;
}
}
然后编写services.xml文件,内容如下:
< serviceGroup >
      < service name = "FaultService" >
           < description >
                 This is the service for revoking certificate.
           </ description >
           < parameter name = "ServiceClass" locked = "false" >
                 l.z.z.FaultService
           </ parameter >
           < operation name = "testFault" >
                 < messageReceiver
           class = "org.apache.axis2.receivers.RawXMLINOutMessageReceiver" />
                 < actionMapping > urn:testFault </ actionMapping >
           </ operation >
      </ service >
</ serviceGroup >
由于本文假设读者已经有axis2开发Web Service的基础,所以对于以上类及配置文件不做解释,敬请原谅。
打包成FaultService.aar文件,文件中包含内容如下:
FaultService.aar
---l
---z
---z
---FaultService.class
---META-INF
---MANIFEST.MF
---services.xml
将该aar包放置到${TOMCAT_HOME}/webapps/axis2/WEB-INF/services目录下。
启动Tomcat,进入 http://localhost:{port}/axis2
然后选择Services,察看服务是否部署成功,如果已经部署成功,进入下一步骤,否则,请重新检查以上各个步骤。成功后应该如下图所示:
2执行TestFaultService类,可以看到错误消息如下:
(类代码参照上面列出的类)
Transport error 500 . Error Message is <html><head><title>Apache Tomcat/5.5.17 - Error report</title><style><!--H1 {color:white;background-color:#525D76;font-size:22px;} H2 {color:white;background-color:#525D76;font-size:16px;} H3 {color:white;background-color:#525D76;font-size:14px;} BODY {color:black;background-color:white;} B {color:white;background-color:#525D76;} P {background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>org.apache.axiom.soap.SOAPProcessingException: Expecting SOAP 1.1 implementation of SOAP Fault Code. But received some other implementation
      org.apache.axiom.soap.impl.llom.soap11.SOAP11FaultImpl.setCode(SOAP11FaultImpl.java:81)
      org.apache.axis2.engine.AxisEngine.extractFaultInformationFromMessageContext( AxisEngine.java:330 )
      org.apache.axis2.engine.AxisEngine.createFaultMessageContext( AxisEngine.java:249 )
      org.apache.axis2.transport.http.AxisServlet.handleFault( AxisServlet.java:317 )
      org.apache.axis2.transport.http.AxisServlet.doPost( AxisServlet.java:277 )
      javax.servlet.http.HttpServlet.service( HttpServlet.java:709 )
      javax.servlet.http.HttpServlet.service( HttpServlet.java:802 )
其中红色的部分是问题的关键,该部分意思是说,客户端期望获得的是一个SOAP 1.1的SOAP Fault Code,但是,我们实际提供的却是一个1.2的实现,所以客户端处理不了,就抛出了异常,而实际出异常的地方那个是红色字体下面的蓝色字体: SOAP11FaultImpl.setCode时,由于是一个SOAP1.2的SOAP Fault Code,所以不能够处理,只能跑出异常。
而通过使用SOAPMonitor观察到的传入SOAP请求消息是:
注意,Axis2自动的将传入的消息加上一层封装,在传输过程中(没有到达Web Service方法testFault之前)是以这个形式传输的,而Axis2使用的默认的SOAP版本是1.1,所以,不管在FaultService类中构造的AxisFault是SOAP11还是SOAP12,最后都会试图将其转换为SOAP11的格式,而一旦此时出现版本冲突,就会发生异常。
AxisFault还没有返回到客户端,就已经发生了异常(上图中SOAPResponse内容为空)。
解决办法一:
将SOAP12的Fault转换为SOAP11的Fault,这样可以传出SOAP11构造的SOAPFault,但是,名称却和SOAP12一致(比如服务器端异常并不是使用SOAP11的”Server”,而是SOAP12的”Receiver”)。这种办法虽然可以实行,但是一旦客户端是SOAP12怎么办,缺少共通性。
解决办法二:
在构造SOAPFault时进行判断,如果客户端使用的是SOAP12,则使用SOAP12Factory来构造,否则使用SOAP11来构造。
这时,就需要在客户端设置使用的SOAP版本,通过一下方法:
Options options = new Options ();
options.setSoapVersionURI(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
这样,就可以设置在传输过程中使用的SOAP封装是SOAP12版本。
这时,通过SOAPMonitor观察到的SOAP请求和响应的消息为:
只所以会有这样的不同是因为通过使用
options.setSoapVersionURI(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
设置了将被使用的SOAP的版本。
由于有些客户端可能使用的是不支持SOAP12版本的SOAP协议,所以,有时候需要将SOAP11进行到SOAP12的装换。

这篇关于axis2中关于AxisFault的说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/947419

相关文章

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

mybatis-plus QueryWrapper中or,and的使用及说明

《mybatis-plusQueryWrapper中or,and的使用及说明》使用MyBatisPlusQueryWrapper时,因同时添加角色权限固定条件和多字段模糊查询导致数据异常展示,排查发... 目录QueryWrapper中or,and使用列表中还要同时模糊查询多个字段经过排查这就导致只要whe

SpringBoot改造MCP服务器的详细说明(StreamableHTTP 类型)

《SpringBoot改造MCP服务器的详细说明(StreamableHTTP类型)》本文介绍了SpringBoot如何实现MCPStreamableHTTP服务器,并且使用CherryStudio... 目录SpringBoot改造MCP服务器(StreamableHTTP)1 项目说明2 使用说明2.1

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro

zookeeper端口说明及介绍

《zookeeper端口说明及介绍》:本文主要介绍zookeeper端口说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、zookeeper有三个端口(可以修改)aVNMqvZ二、3个端口的作用三、部署时注意总China编程结一、zookeeper有三个端口(可以

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化