今天进入AXIS之四,如何抛出一个你的自定义异常。本来想连传文件一起介绍的。后来感觉一篇blog里太多的内容也不太好,看起来太辛苦,还是慢慢来,废话不多进入正题。
上一篇介绍了如果在Server和Client端传递一个自己的对象。有些人也许会问传递异常行不行?答案是可以。只不过传递异常的配置要稍微复杂一些。空口无凭,我还是用点代码来说明。今天的例子稍微复杂点,用一下数据库(MySQL)。首先创建表和输入测试数据。
create table users(id integer primary key, name varchar(20) not null);
insert into users values(1, 'Lincoln'),(2, 'Michael'),(4, 'Mahone'),(6, 'Sara');
一个user表,4条记录。等会我们client段会发送一个SOAP request给server段,之后server段返回客户要的数据,如果没有则抛出一个自定义异常。表建立完成之后来编写JavaBean。
package com.chnic.bean;
public class UserBean implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String name;
public UserBean(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Bean有两个属性,Id和Name。client会根据ID来取要的Name。编写完Bean之后我们来编写Customer Exception的代码。
package com.chnic.exception;
import java.rmi.RemoteException;
public class NoSuchUserException extends RemoteException {
private String errorMessage = "No such user: ";
private int id;
private static final long serialVersionUID = 1L;
public NoSuchUserException() {
}
public void printErrorMessage(){
System.out.println(errorMessage + id);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
NoSuchUserException这个类会记录在数据库没有相应数据的ID的值,然后返回给Client。值得注意的是,因为这个是个远程异常。所以要继承RemoteException这个类。两个要transfer的Bean完成之后。我们来编写Service Ojbect的代码。
package com.chnic.webservice;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.chnic.bean.UserBean;
import com.chnic.exception.NoSuchUserException;
import java.sql.DriverManager;
public class CheckUserInfo {
private String url = "jdbc:mysql://localhost:3306/test";
private String user = "root";
private String password = "root";
public CheckUserInfo(){
}
public Connection getConn(){
try {
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public UserBean checkUser(int id) throws NoSuchUserException{
Connection conn = null;
try {
conn = this.getConn();
PreparedStatement statement =
conn.prepareStatement("select * from users where id = ?");
statement.setInt(1, id);
ResultSet rs = statement.executeQuery();
boolean flag = false;
UserBean user = null;
while(rs.next()){
flag = true;
user = new UserBean();
user.setId(id);
user.setName(rs.getString(2));
}
rs.close();
if(flag)
return user;
else{
NoSuchUserException userException = new NoSuchUserException();
userException.setId(id);
throw userException;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.closeConn(conn);
}
return null;
}
public void closeConn(Connection conn){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
因为是Demo代码,代码写的比较粗糙,反正就是为了个演示。大家能看出来效果就好了。代码很简单,接收到一个id,然后在数据库里做匹配。如果找到匹配的了返回那个userbean,如果没找到就throw一个Exception出去。在这里多嘴一句。传递的Bean赋值的时候一定要用setXXX方法,不能用构造函数传递,否则传递过去之后属性值会丢失。 你编写的那个Bean一定要严格遵循JavaBean规范。
之后我们来看WSDD发布文件。比起之前我们看到的WSDD文件,这次的稍微有点点复杂。
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="AxisExceptionTest" provider="java:RPC">
<namespace>http://faults.samples</namespace>
<parameter name="className" value="com.chnic.webservice.CheckUserInfo"/>
<parameter name="allowedMethods" value="checkUser"/>
<parameter name="scope" value="Session"/>
<operation name="checkUser"
qname="operNS:checkUser"
xmlns:operNS="getSingleUser"
returnQName="getUserReturn"
returnType="rtns:User"
xmlns:rtns="http://faults.samples" >
<parameter name="id" type="tns:int"
xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
<fault name="NoSuchEmployeeFault"
qname="fns:fault"
xmlns:fns="http://faults.samples"
class="samples.faults.NoSuchEmployeeFault"
type="tns:NoSuchUserFault"
xmlns:tns="http://faults.samples"/>
</operation>
<typeMapping qname="myns:NoSuchUserFault"
xmlns:myns="urn:CustomerFault"
type="java:com.chnic.exception.NoSuchUserException"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<typeMapping qname="myns:User"
xmlns:myns="urn:CustomerBean"
type="java:com.chnic.bean.UserBean"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</service>
</deployment>
首先不同的是多了个命名空间也就是namespace节点,等会测试代码中会看到用途。除了namespace之外还有operation这个节点和里面的parameter和fault子节点。先来介绍operation这个节点的属性。
name:操作名称或者方法名称,这个值会和你server发布的相关方法名匹配,所以要和方法名相同。
qname:针对这个operation的限定名。
xmlns:针对这个qname的命名空间也就是namespace。(不明白的可以看上一篇博文)
returnQName:这个元素节点所对应的方法返回出来对象的Qname。
returnType:返回类型,注意和下面的typemapping的qname比较。
parameter节点是这个operation指代的方法的参数,fault节点代表要这个方法要抛出的异常。异常也需要被mapping。下面的typemapping做的也是这样的事情。这两个元素的节点的属性和operation都是类似,对以一下大概就知道什么意思了。在这里也不多解释了。现在来看测试代码。
package com.chnic.test;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import com.chnic.bean.UserBean;
import com.chnic.exception.NoSuchUserException;
public class TestException {
public static void main(String[] args){
String uri = "http://faults.samples";
String serviceName = "EmployeeInfoService";
ServiceFactory serviceFactory;
String url = "http://localhost:8080/axis/services/AxisExceptionTest";
try {
serviceFactory = ServiceFactory.newInstance();
QName serQ = new QName(uri, serviceName);
Service service = serviceFactory.createService(serQ);
TypeMappingRegistry registry = service.getTypeMappingRegistry();
TypeMapping map = registry.getDefaultTypeMapping();
QName employeeQName = new QName("urn:CustomerBean", "User");
map.register(UserBean.class, employeeQName,
new BeanSerializerFactory(UserBean.class, employeeQName),
new BeanDeserializerFactory(UserBean.class, employeeQName));
QName faultQName = new QName("urn:CustomerFault", "NoSuchUserFault");
map.register(NoSuchUserException.class, faultQName,
new BeanSerializerFactory(NoSuchUserException.class, faultQName),
new BeanDeserializerFactory(NoSuchUserException.class, faultQName));
Call call = service.createCall();
call.setTargetEndpointAddress(url);
call.setOperationName( new QName(uri, "checkUser") );
Object obj = call.invoke(new Object[]{ new Integer(3)});
UserBean user = (UserBean) obj;
System.out.println(user.getName());
} catch (ServiceException e) {
e.printStackTrace();
}catch(NoSuchUserException e){
e.printErrorMessage();
}catch (RemoteException e) {
e.printStackTrace();
}
}
}
看到第一个申明的uri了么?我们通过这个uri和service来取得对应的service。 之后我们用TypeMappingRegistry得到一个默认的TypeMapping。在map里面映射我们的bean。之后和往常的代码一样没有特别的。invoke唤起方法,返回UserBean,并打出UserBean的name。值得注意的是后面的catch部分,我们catch了一个我们自己申明的NoSuchUserException,抓住这个异常之后打出我们要的错误信息。
因为1 2 4 6在数据库里都是有对应的数值的,所以当我要查找ID为3个user的name的时候,service就会返回一个NoSuchUserException给我。之后在本地抓住这个exception之后,控制台打出了如下信息。
No such user: 3
如果输入的是1 2 4 6的话,则会返回user的名字。在这里就不测试了。各位自己可以试试。
分享到:
相关推荐
标题 "Axis 自动生成WebService" 涉及到的是在IT行业中创建和使用Web服务的一个关键工具——Axis。Web服务是一种基于互联网的软件应用,允许不同系统之间的数据交换,通常使用XML作为数据格式,SOAP协议进行通信。...
### WebService之Axis2经典教程 #### 一、概述 随着信息技术的发展,Web Service作为一种重要的分布式计算模式,已经成为实现服务导向架构(SOA)的关键技术之一。Axis2作为一款流行的Web Service引擎,不仅具备高...
WebService——AXIS详解 在IT领域,WebService是一种基于标准的、平台无关的、可以在不同系统之间交换数据的方式。它利用XML(可扩展标记语言)作为数据格式,HTTP作为传输协议,SOAP(简单对象访问协议)作为消息...
- **自定义模块开发**:深入学习如何开发自定义的Axis2模块以增强服务的功能。 ### 结论 通过以上知识点的介绍可以看出,Axis2不仅在基础功能上提供了丰富的支持,还在高级特性方面具有很强的灵活性和扩展性。无论...
3.6抛出异常.......................................60 3.7传递文件.......................................67 4.AXIS的常用的命令和调试工具的使用................72 4.1AXIS的常用命令:........................
在Axis2中,开发者可以利用简单的POJO(Plain Old Java Object)创建无须额外配置的WebService。这种模式极大地简化了开发流程,提高了效率。例如,一个包含业务逻辑的Java类可以直接暴露为WebService,无需复杂的...
Spring 框架则是一个全面的企业级应用开发框架,提供了诸如依赖注入、AOP(面向切面编程)、事务管理等功能。将 Quartz 与 Spring 整合,可以方便地在 Spring 应用程序中使用 Quartz 的功能。 整合 Quartz 和 ...
【Web Service 那点事儿(2)—— 使用 CXF 开发 SOAP 服务】 Web Service是一种基于标准协议的,用于不同系统间交换数据的技术。SOAP(Simple Object Access Protocol)是Web Service常用的一种通信协议,它定义了...
### Aris WebService详解与实践 #### 一、引言 在现代软件开发领域,Web服务作为连接不同系统的关键技术,扮演着至关重要的角色。它允许应用程序之间进行跨平台、跨语言的数据交换与功能调用,极大地提高了软件的...
- **云连接(Cloud Connect)**:Mule 3引入了一种全新的特性——云连接,它允许企业以简单安全的方式利用云技术进行数据和服务的整合。 - **Integration Beans**:这些是轻量级、可重用的接口,用于Web技术的连接扩展...