hession client server exception

RPC異常處理概述

RPC異常處理指是,當客戶端調用遠端的服務,若是服務執行過程當中發生異常,這個異常可否序列到客戶端?java

若是服務在執行過程當中可能發生異常,那麼在服務接口的聲明中,就該聲明該接口可能拋出的異常。web

在Hessian中,服務器端發生異常,能夠將異常信息從服務器端序列化到客戶端,由於Exception自己是實現了Serializable的,所以,咱們在自定義異常時,不須要顯式的讓自定義的服務器

異常實現Serializable接口app

舉例

繼續以【RPC框架Hessian二】中的代碼爲例,修改服務的save方法,刻意的讓服務器端的代碼拋出異常(拋出的是運行時異常,受檢異常與此相似)框架

package com.tom.hessian.server;

import com.tom.hessian.common.ComplexModel;
import com.tom.hessian.common.IComplexModelService;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by yuzhitao on 14-9-2.
 */
public class ComplexModelService implements IComplexModelService {
  private Map<Integer,ComplexModel> models = new HashMap<Integer, ComplexModel>();
  @Override
  public void save(ComplexModel model) {
    if (model.getId() == null){
      throw new IllegalArgumentException("id could not be null");
    }

    if (model.getId() == 1) { //客戶端的model的id爲1,所以會發生unchecked exception
      throw new IllegalArgumentException("id could not be 1");
    }

    models.put(model.getId(), model);
  }

  @Override
  public ComplexModel read(Integer modelId) {
    return models.get(modelId);
  }
}

當客戶端的model的id爲1時,調用save方法,拋出webapp

if (model.getId() == 1) { //客戶端的model的id爲1,所以會發生unchecked exception
            throw new IllegalArgumentException("id could not be 1");
        }

此時服務器端沒有拋出異常,而客戶端拋出異常:ide

Exception in thread "main" java.lang.IllegalArgumentException: id could not be 1
  at com.tom.hessian.server.ComplexModelService.save(ComplexModelService.java:21)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:302)
  at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:198)
  at com.caucho.hessian.server.HessianServlet.invoke(HessianServlet.java:399)
  at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:379)
  at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
  at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
  at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
  at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
  at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
  at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
  at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
  at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
  at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
  at org.mortbay.jetty.Server.handle(Server.java:324)
  at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
  at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:842)
  at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:648)
  at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
  at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
  at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
  at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:450)

Hessian服務器端異常處理源代碼分析

在Hessian的HessianSkeleton類的invoke方法中,經過反射調用服務代碼:this

try {
      result = method.invoke(service, values); //調用的服務端類、參數和方法
    } catch (Exception e) { //捕獲異常
      Throwable e1 = e;
      if (e1 instanceof InvocationTargetException)
        e1 = ((InvocationTargetException) e).getTargetException();

      log.log(Level.FINE, this + " " + e1.toString(), e1);

      out.writeFault("ServiceException", 
        escapeMessage(e1.getMessage()), 
        e1);//將異常信息序列到客戶端
      out.close();
      return;
    }
相關文章
相關標籤/搜索