八、WebService处理异常信息

在数据传递和远程调用过程中,有时候调用者传递错误的数据和是调用的方法错误。那我们怎样处理这个错误?方法有很多,这里介绍下用异常处理远程调用的错误方法。

1、编写服务器端的异常类,在远处调用中(WebService)异常类继承RemoteException,记得要序列化下,代码如下:

 

代码
 
   
package com.hoo.exception;

import java.rmi.RemoteException;

/**
* <b>function:</b>定制服务器端异常信息
*
@author hoojo
* @createDate Dec 17, 2010 00:00:52 AM
* @file RemoteServerException.java
* @package com.hoo.exception
* @project AxisWebService
* @blog
http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
*
@version 1.0
*/
public class RemoteServerException extends RemoteException {
private static final long serialVersionUID = 1L ;
private String message;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this .message = message;
}

public RemoteServerException() {
System.out.println(
" Remote Servier Exception " );
}

public void showMessage() {
System.out.println(
this .message);
}
}

 

 

2、编写客户端的异常信息类,和前面远程传递对象一样。因为我们并不知道服务器端的异常信息类代码,但是通过wsdl的xml文件的描述我们可以知道远程异常类的基本信息:方法、方法参数、返回值等信息,下面是客户端的异常信息类代码:

 

代码
 
   
package com.hoo.exception;

import java.rmi.RemoteException;

/**
* <b>function:</b>本地客户端异常信息
*
@author hoojo
* @createDate Dec 17, 2010 00:05:30 AM
* @file LocalClientException.java
* @package com.hoo.exception
* @project AxisWebService
* @blog
http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
*
@version 1.0
*/
public class LocalClientException extends RemoteException {

private static final long serialVersionUID = 3 ;
private String message;
public String getMessage() {
return message;
}

public void setMessage(String message) {
this .message = message;
}

public LocalClientException() {
System.out.println(
" Local Client Exception " );
}

public void showMessage() {
System.out.println(
this .message);
}
}

内容几乎一样,就是类名称不同。

3、编写触发异常的WebService服务器端代码

 

代码
 
   
package com.hoo.service;

import com.hoo.exception.RemoteServerException;

/**
* <b>function:</b>发出异常信息
*
@author hoojo
* @createDate Dec 17, 2010 00:08:07 AM
* @file ThrowException.java
* @package com.hoo.service
* @project AxisWebService
* @blog
http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
*
@version 1.0
*/
public class ThrowException {

public void doException() throws RemoteServerException {
RemoteServerException rse
= new RemoteServerException();
rse.setMessage(
" 服务器端出现异常 " );
throw rse;
}
}

 

 

4、定制wsdd文件,发布当前WebService。

 

代码
 
   
<? xml version="1.0" encoding="UTF-8" ?>
< deployment xmlns ="http://xml.apache.org/axis/wsdd/"
xmlns:java
="http://xml.apache.org/axis/wsdd/providers/java" >
< service name ="ThrowException" provider ="java:RPC" >
< parameter name ="className" value ="com.hoo.service.ThrowException" />
< parameter name ="allowedMethods" value ="*" />
< parameter name ="scope" value ="Session" />

< operation name ="doException" qname ="operNS:doException" xmlns:operNS ="doException" >
< fault name ="RemoteServerExceptionFault" qname ="fut:fault" xmlns:fut ="RemoteServerExceptionFault" type ="tns:RemoteServerException" xmlns:tns ="RemoteServerException" />
</ operation >
< typeMapping qname ="myNSD:Exception" xmlns:myNSD ="ns:CustomException" languageSpecificType ="java:com.hoo.exception.RemoteServerException" serializer ="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer
="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle ="http://schemas.xmlsoap.org/soap/encoding/" />
</ service >
</ deployment >

 

 

特别说明,这里多了3个xml标签元素。operation、fault、typeMapping,下面将依次介绍。

operation看看这个标签中的内容,就和我们最先看到的wsdl的xml文件中的方法标签很像。没错这里它指定的就是一个方法,operation就指定触发异常信息的方法。和你在服务器端触发异常的WebService的方法对应,qname是限定名称,xmlns是限定名称的命名空间。

fault的name一个名称,可以随便取。type就是你服务器端抛出异常的类型,这里服务器端抛出的RemoteServerException,所以类型就是RemoteServerException。如果你服务器端抛出的是NullPointException这里的type就是NullPointException。

typeMapping这个也很关键,和前面的beanMapping有几分相似特别是前面一段qname、xmlns、以及languageSpecificType都是一样的,用法也一样。分别和客户端的new QName("ns:CustomException", "Exception");中的对应;其中serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"就是序列化的工厂类,deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"这个不说你也知道是反序列化的工厂类,encodingStyle这个是编码样式。

5、用定制好的wsdd文件发布我们的WebService,依旧是命令行:

C:\SoftWare\tomcat-5.0.28\tomcat-5.0.28\webapps\AxisWebService\WEB-INF>java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8080/AxisWebService/services/AdminService deployException.wsdd

发布完成后,在浏览器中输入:

http://localhost:8080/AxisWebService/servlet/AxisServlet

即可查看刚才发布的服务信息,但是你点击wsdl链接的时候并不能看到xml的内容,那是因为服务器端抛出了异常导致的。这个不是错误是正常的,不过你可以在web.xml中配置异常的信息页面。

6、编写客户端代码,这里的代码和传递对象的WebService也很类似

 

代码
 
   
package com.hoo.client;

import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import com.hoo.exception.LocalClientException;
import com.hoo.exception.RemoteServerException;

public class TryExceptionClient {

/**
* <b>function:</b>捕捉服务器端异常信息的WebService的客户端
*
@author hoojo
* @createDate Dec 17, 2010 00:12:56 AM
*
@param args
*
@throws ServiceException
*
@throws RemoteException
*/
public static void main(String[] args) {
String url
= " http://localhost:8080/AxisWebService/services/ThrowException " ;
Service service
= new Service();
try {
Call call
= (Call) service.createCall();

/**
* 注册异常类信息和序列化类
* ns:CustomException 和 wsdd 配置文件中的typeMapping中的xmlns:myNSD="ns:CustomException"的对应
* Exception 和 wsdd 配置文件中的typeMapping中的qname="myNSD:Exception"的Exception对应
*/
QName qn
= new QName( " ns:CustomException " , " Exception " );
/**
* 这里配置的LocalClientException,会将服务器端的RemoteServerException转换成本地的异常信息LocalClientException
*/
call.registerTypeMapping(LocalClientException.
class , qn,
new BeanSerializerFactory(LocalClientException. class ,qn),
new BeanDeserializerFactory(LocalClientException. class , qn));
call.setOperationName(
new QName(url, " doException " ));

call.setTargetEndpointAddress(url);
call.invoke(
new Object[]{});
}
catch (RemoteServerException e) {
e.showMessage();
System.out.println(
" RemoteServerException: " + e.getMessage());
e.printStackTrace();
}
catch (LocalClientException e) {
e.showMessage();
System.out.println(
" LocalClientException: " + e.getMessage());
e.printStackTrace();
}
catch (RemoteException e) {
System.out.println(
" RemoteException: " + e.getMessage());
e.printStackTrace();
}
catch (ServiceException e) {
System.out.println(
" ServiceException: " + e.getMessage());
e.printStackTrace();
}
}
}

 

 

看上面的registerTypeMapping和wsdd文件中的typeMapping有些相同之处吧,下面运行下上面的代码,结果如下:

 

代码
 
   
Local Client Exception
服务器端出现异常
LocalClientException:服务器端出现异常
com.hoo.exception.LocalClientException: 服务器端出现异常
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at org.apache.axis.encoding.ser.BeanDeserializer.
< init > (BeanDeserializer.java: 104 )
at org.apache.axis.encoding.ser.BeanDeserializerFactory.getGeneralPurpose(BeanDeserializerFactory.java:
89 )
at org.apache.axis.encoding.ser.BaseDeserializerFactory.getDeserializerAs(BaseDeserializerFactory.java:
89 )
at org.apache.axis.encoding.DeserializationContext.getDeserializer(DeserializationContext.java:
464 )
at org.apache.axis.encoding.DeserializationContext.getDeserializerForType(DeserializationContext.java:
547 )
at org.apache.axis.message.SOAPFaultDetailsBuilder.onStartChild(SOAPFaultDetailsBuilder.java:
157 )
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:
1035 )
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:
227 )
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:
696 )
at org.apache.axis.Message.getSOAPEnvelope(Message.java:
435 )
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:
62 )
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:
206 )
at org.apache.axis.client.Call.invokeEngine(Call.java:
2784 )
at org.apache.axis.client.Call.invoke(Call.java:
2767 )
at org.apache.axis.client.Call.invoke(Call.java:
2443 )
at org.apache.axis.client.Call.invoke(Call.java:
2366 )
at org.apache.axis.client.Call.invoke(Call.java:
1812 )
at com.hoo.client.TryExceptionClient.main(TryExceptionClient.java:
44 )

 

 

服务器端控制台会输出:Remote Servier Exception

这是在创建异常的时候,在构造函数中输出的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值