zoukankan      html  css  js  c++  java
  • 八、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

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

  • 作者:hoojo
    出处:
    blog:http://blog.csdn.net/IBM_hoojo
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权所有,转载请注明出处 本文出自:
分享道版权所有,欢迎转载,转载请注明出处,谢谢
收藏
关注
评论
查看全文
  • 相关阅读:
    Linux开机启动流程(centos7)
    系统平均负载
    Linux基础命令screen(后台管理程序)
    Linux基础命令nohup & (管理进程的后台)
    Linux基础命令kill(终止进程)
    Linux基础命令top(动态显示进程状态)
    Linux基础练习题答案7.31
    Linux基础命令ps
    Swap虚拟内存(内存满了怎么办?)
    50 | 深入浅出网站高可用架构设计
  • 原文地址:https://www.cnblogs.com/hoojo/p/1911384.html
  • Copyright © 2011-2022 走看看