posts - 64,  comments - 9,  trackbacks - 0

          利用AXIS開發Webservice(四) —— 如何拋出自定義異常

          關鍵字: webservice axis throw customer exception

          今天進入AXIS之四,如何拋出一個你的自定義異常。本來想連傳文件一起介紹的。后來感覺一篇blog里太多的內容也不太好,看起來太辛苦,還是慢慢來,廢話不多進入正題。

           

          上一篇介紹了如果在Server和Client端傳遞一個自己的對象。有些人也許會問傳遞異常行不行?答案是可以。只不過傳遞異常的配置要稍微復雜一些。空口無憑,我還是用點代碼來說明。今天的例子稍微復雜點,用一下數據庫(MySQL)。首先創建表和輸入測試數據。

          Sql代碼 復制代碼
          1. create table users(id integer primary keyname varchar(20) not null);   
          2.     
          3. insert into users values(1, 'Lincoln'),(2, 'Michael'),(4, 'Mahone'),(6, 'Sara');  

           

          一個user表,4條記錄。等會我們client段會發送一個SOAP request給server段,之后server段返回客戶要的數據,如果沒有則拋出一個自定義異常。表建立完成之后來編寫JavaBean。

          Java代碼 復制代碼
          1. package com.chnic.bean;   
          2.   
          3. public class UserBean implements java.io.Serializable{   
          4.   
          5.     private static final long serialVersionUID = 1L;   
          6.     private int id;   
          7.     private String name;   
          8.        
          9.     public UserBean(){   
          10.            
          11.     }   
          12.     public int getId() {   
          13.         return id;   
          14.     }   
          15.     public void setId(int id) {   
          16.         this.id = id;   
          17.     }   
          18.     public String getName() {   
          19.         return name;   
          20.     }   
          21.     public void setName(String name) {   
          22.         this.name = name;   
          23.     }   
          24. }  

           

          Bean有兩個屬性,Id和Name。client會根據ID來取要的Name。編寫完Bean之后我們來編寫Customer Exception的代碼。

          Java代碼 復制代碼
          1. package com.chnic.exception;   
          2.   
          3. import java.rmi.RemoteException;   
          4.   
          5. public class NoSuchUserException extends RemoteException {   
          6.   
          7.     private String errorMessage = "No such user: ";   
          8.     private int id;   
          9.     private static final long serialVersionUID = 1L;   
          10.   
          11.     public NoSuchUserException() {   
          12.     }   
          13.   
          14.     public void printErrorMessage(){   
          15.         System.out.println(errorMessage + id);   
          16.     }   
          17.   
          18.     public int getId() {   
          19.         return id;   
          20.     }   
          21.   
          22.     public void setId(int id) {   
          23.         this.id = id;   
          24.     }   
          25. }  

           

          NoSuchUserException這個類會記錄在數據庫沒有相應數據的ID的值,然后返回給Client。值得注意的是,因為這個是個遠程異常。所以要繼承RemoteException這個類。兩個要transfer的Bean完成之后。我們來編寫Service Ojbect的代碼。

          Java代碼 復制代碼
          1. package com.chnic.webservice;   
          2.   
          3. import java.sql.Connection;   
          4. import java.sql.PreparedStatement;   
          5. import java.sql.ResultSet;   
          6. import java.sql.SQLException;   
          7.   
          8. import com.chnic.bean.UserBean;   
          9. import com.chnic.exception.NoSuchUserException;   
          10. import java.sql.DriverManager;   
          11.   
          12. public class CheckUserInfo {   
          13.     private String url = "jdbc:mysql://localhost:3306/test";   
          14.     private String user = "root";   
          15.     private String password = "root";   
          16.        
          17.        
          18.     public CheckUserInfo(){    
          19.            
          20.     }   
          21.        
          22.     public Connection getConn(){   
          23.         try {   
          24.             Class.forName("com.mysql.jdbc.Driver");   
          25.             return DriverManager.getConnection(url, user, password);   
          26.         } catch (ClassNotFoundException e) {   
          27.             e.printStackTrace();   
          28.         } catch (SQLException e) {   
          29.             e.printStackTrace();   
          30.         }   
          31.         return null;   
          32.     }   
          33.        
          34.     public UserBean checkUser(int id) throws NoSuchUserException{   
          35.         Connection conn = null;   
          36.         try {   
          37.             conn = this.getConn();   
          38.             PreparedStatement statement =    
          39.                 conn.prepareStatement("select * from users where id = ?");   
          40.             statement.setInt(1, id);   
          41.             ResultSet rs = statement.executeQuery();   
          42.             boolean flag = false;   
          43.             UserBean user = null;   
          44.                 
          45.             while(rs.next()){   
          46.                 flag = true;   
          47.                 user = new UserBean();   
          48.                 user.setId(id);   
          49.                 user.setName(rs.getString(2));   
          50.             }   
          51.             rs.close();   
          52.             if(flag)   
          53.                 return user;   
          54.             else{   
          55.                 NoSuchUserException userException = new NoSuchUserException();   
          56.                 userException.setId(id);   
          57.                    
          58.                 throw userException;   
          59.             }   
          60.         } catch (SQLException e) {   
          61.             e.printStackTrace();   
          62.         }finally{   
          63.             this.closeConn(conn);   
          64.         }   
          65.         return null;   
          66.     }   
          67.        
          68.     public void closeConn(Connection conn){    
          69.         try {   
          70.             conn.close();   
          71.         } catch (SQLException e) {   
          72.             e.printStackTrace();   
          73.         }   
          74.     }   
          75. }  
           

          因為是Demo代碼,代碼寫的比較粗糙,反正就是為了個演示。大家能看出來效果就好了。代碼很簡單,接收到一個id,然后在數據庫里做匹配。如果找到匹配的了返回那個userbean,如果沒找到就throw一個Exception出去。在這里多嘴一句。傳遞的Bean賦值的時候一定要用setXXX方法,不能用構造函數傳遞,否則傳遞過去之后屬性值會丟失。 你編寫的那個Bean一定要嚴格遵循JavaBean規范。  

          之后我們來看WSDD發布文件。比起之前我們看到的WSDD文件,這次的稍微有點點復雜。

           

          Xml代碼 復制代碼
          1. <deployment xmlns="http://xml.apache.org/axis/wsdd/"    
          2.     xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">  
          3.        
          4.     <service name="AxisExceptionTest" provider="java:RPC">  
          5.         <namespace>http://faults.samples</namespace>  
          6.         <parameter name="className" value="com.chnic.webservice.CheckUserInfo"/>  
          7.         <parameter name="allowedMethods" value="checkUser"/>  
          8.         <parameter name="scope" value="Session"/>  
          9.            
          10.         <operation name="checkUser"    
          11.                    qname="operNS:checkUser"    
          12.                    xmlns:operNS="getSingleUser"    
          13.                    returnQName="getUserReturn"    
          14.                    returnType="rtns:User"    
          15.                    xmlns:rtns="http://faults.samples" >  
          16.                       
          17.             <parameter name="id" type="tns:int"    
          18.                 xmlns:tns="http://www.w3.org/2001/XMLSchema"/>              
          19.             <fault name="NoSuchEmployeeFault"    
          20.                    qname="fns:fault"    
          21.                    xmlns:fns="http://faults.samples"    
          22.                    class="samples.faults.NoSuchEmployeeFault"    
          23.                    type="tns:NoSuchUserFault"    
          24.                    xmlns:tns="http://faults.samples"/>  
          25.         </operation>  
          26.            
          27.                       
          28.         <typeMapping qname="myns:NoSuchUserFault"    
          29.             xmlns:myns="urn:CustomerFault"  
          30.             type="java:com.chnic.exception.NoSuchUserException"  
          31.             serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"  
          32.             deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"  
          33.             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
          34.            
          35.         <typeMapping qname="myns:User"  
          36.             xmlns:myns="urn:CustomerBean"  
          37.             type="java:com.chnic.bean.UserBean"  
          38.             serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"  
          39.             deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"  
          40.             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
          41.     </service>  
          42. </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都是類似,對以一下大概就知道什么意思了。在這里也不多解釋了。現在來看測試代碼。

           

          Java代碼 復制代碼
          1. package com.chnic.test;   
          2.   
          3. import java.rmi.RemoteException;   
          4.   
          5. import javax.xml.namespace.QName;   
          6. import javax.xml.rpc.Call;   
          7. import javax.xml.rpc.Service;   
          8. import javax.xml.rpc.ServiceException;   
          9. import javax.xml.rpc.ServiceFactory;   
          10. import javax.xml.rpc.encoding.TypeMapping;   
          11. import javax.xml.rpc.encoding.TypeMappingRegistry;   
          12.   
          13. import org.apache.axis.encoding.ser.BeanDeserializerFactory;   
          14. import org.apache.axis.encoding.ser.BeanSerializerFactory;   
          15.   
          16. import com.chnic.bean.UserBean;   
          17. import com.chnic.exception.NoSuchUserException;   
          18.   
          19.   
          20. public class TestException {   
          21.   
          22.     public static void main(String[] args){   
          23.         String uri = "http://faults.samples";   
          24.         String serviceName = "EmployeeInfoService";   
          25.         ServiceFactory serviceFactory;   
          26.         String url = "http://localhost:8080/axis/services/AxisExceptionTest";   
          27.         try {   
          28.             serviceFactory = ServiceFactory.newInstance();   
          29.             QName serQ = new QName(uri, serviceName);   
          30.             Service service = serviceFactory.createService(serQ);   
          31.                
          32.             TypeMappingRegistry registry = service.getTypeMappingRegistry();   
          33.             TypeMapping map = registry.getDefaultTypeMapping();   
          34.                            
          35.             QName employeeQName = new QName("urn:CustomerBean""User");   
          36.             map.register(UserBean.class, employeeQName,    
          37.                 new BeanSerializerFactory(UserBean.class, employeeQName),    
          38.                 new BeanDeserializerFactory(UserBean.class, employeeQName));   
          39.   
          40.             QName faultQName = new QName("urn:CustomerFault""NoSuchUserFault");   
          41.             map.register(NoSuchUserException.class, faultQName,    
          42.                 new BeanSerializerFactory(NoSuchUserException.class, faultQName),    
          43.                 new BeanDeserializerFactory(NoSuchUserException.class, faultQName));   
          44.                        
          45.             Call call = service.createCall();   
          46.             call.setTargetEndpointAddress(url);   
          47.                
          48.             call.setOperationName( new QName(uri, "checkUser") );   
          49.             Object obj = call.invoke(new Object[]{ new Integer(3)});   
          50.             UserBean user = (UserBean) obj;   
          51.             System.out.println(user.getName());   
          52.                            
          53.         } catch (ServiceException e) {   
          54.             e.printStackTrace();   
          55.         }catch(NoSuchUserException e){   
          56.             e.printErrorMessage();   
          57.         }catch (RemoteException e) {           
          58.             e.printStackTrace();   
          59.         }   
          60.     }   
          61. }  

           

          看到第一個申明的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的名字。在這里就不測試了。各位自己可以試試。

          posted on 2009-07-03 18:45 super_nini 閱讀(616) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2009年7月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿

          隨筆檔案

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 徐闻县| 乌兰察布市| 乌兰浩特市| 武陟县| 罗山县| 六安市| 马龙县| 株洲县| 教育| 屏南县| 政和县| 扶绥县| 巫溪县| 治多县| 托克逊县| 沙河市| 齐河县| 南昌县| 曲阳县| 鹤庆县| 醴陵市| 宁化县| 和平区| 湄潭县| 清新县| 右玉县| 陵水| 合山市| 康保县| 封开县| 锡林浩特市| 江山市| 保山市| 合作市| 滁州市| 仁布县| 吉木乃县| 定南县| 新田县| 陆河县| 江口县|