基于Spring和hibernate的灵活的异常处理办法_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2336 | 回复: 0   主题: 基于Spring和hibernate的灵活的异常处理办法        下一篇 
gunrose
注册用户
等级:新兵
经验:36
发帖:79
精华:0
注册:2011-7-21
状态:离线
发送短消息息给gunrose 加好友    发送短消息息给gunrose 发消息
发表于: IP:您无权察看 2015-7-16 11:50:43 | [全部帖] [楼主帖] 楼主

Spring exeception


在spring,hibernate中异常的处理都交给了spring框架,在hibernate只需要写很少的代码就可以实现异常的控制。 
在单元测试代码中: 

public final void testFindFunctionById() {
      logger.debug("testFindFunctionById");
      long l1=System.currentTimeMillis();
      String id="4";
      Function function=BeanFactory.getInstance().getRightDelegate().findFunctionById(id, state);
      long l2=System.currentTimeMillis();
      System.out.println("function.getId = "+function.getId());
      System.out.println("function.getName = "+function.getName());
      System.out.println("function.getProtectFunction = "+function.getProtectFunction());
      System.out.println("--------------finish----------------");
      System.out.println("一共用时为 :  "+(l2-l1));
}


在delegate中接受信息: 

public Function findFunctionById(String id, IState state) {
      if (DelegateUtil.isNullParam(id, "id", state)) {
            return null;
      }
      Request req = new Request();
      req.setServiceName(ServiceConsts.FindFunctionByIdProcessor);
      req.setValue("id", id);
      try {
            Response resp = getDelegate().execute(req);
            DelegateUtil.setIState(state, resp);
            Function function = (Function) resp.getValue("function");
            DelegateUtil.setIState(state, resp);
            return function;
      } catch (Exception e) {
            DelegateUtil.handleException(e, "findFunctionById", state);
            return null;
      }
}


在delegate中首先对参数做一般的空指针检查,如下面的代码 

public static boolean isNullParam(Object paramObject, String paramName,
IState state)
{
      if (paramObject == null) {
            logger.error("Parameter " + paramName + " is null;");
            state.setErrCode(ErrorCode.PARAMETER_ERROR);
            return true;
      }
      return false;
}


如果传值是null的话,在state中设置ErrorCode.PARAMETER_ERROR参数直接返回给客户端,客户端根据不同的ErrorCode可以知道问题的所在,并作出相应的操作。 
然后生成一个Request,封装了这次请求的参数,如ServiceName和values。请求分发到相应的service,如 FindFunctionByIdProcessor。Service再将请求分发到service下面的command,command代码如下: 

public class FindFunctionById extends Command
{
      private FunctionDao dao;
      public void setDao(FunctionDao dao) {
            this.dao = dao;
      }
      public void execute(Map params, Map response) throws Exception
      {
            response.put("function",(Function)dao.getById(Function.class, (String) params.get("id")));
      }
      ……
}


在command中把参数接下来调用dao的方法,并把结果放在response中。在delegate就可以在response中取得结果。 
Dao的代码如下: 

public Object getById(Class c, Serializable id) {
      return getHibernateTemplate().get(c, id);
}


在dao中只是调用了spring的类。这个调用流程没有涉及到异常的捕捉。那它是在哪里处理的呢?看下面的代码

public class SequenceProcessor extends BaseProcessor {
      private static Logger logger=Logger.getLogger(SequenceProcessor.class);
      public boolean supports(Component component) {
            return (component instanceof Command);
      }
      public void doActivities(Request request,Response resp) throws Exception {
            logger.info("SequenceProcessor 流程开始 <-- "+getBeanName() );
            Map response = resp.getValues();
            Map params = request.getValues();
            List activities = getActivities();
            for (Iterator it = activities.iterator(); it.hasNext();) {
                  Component component = (Component) it.next();
                  logger.info("活动 : " + component.getBeanName());
                  try {
                        component.init("");
                        component.execute(params, response);
                        component.fini();
                  } catch (Throwable th) {
                        ErrorHandler errorHandler = component.getErrorHandler();
                        if (errorHandler == null) {
                              logger.info("no Errorhandler for Command "+component.getBeanName() +", run processor Errorhandler and abort Command ");
                              ErrorHandler processorerrorHandler=getErrorHandler();
                              if(processorerrorHandler == null){
                                    logger.info("no error handler for this processor, run defaultErrorHandler and abort processor ");
                                    //执行全局的default ErrorHandler; 
                                    ErrorHandler defaultErrorHandler=((ErrorHandler)ContextServiceLocator.getInstance().getBean("defaultErrorHandler"));
                                    if(defaultErrorHandler!=null)
                                    defaultErrorHandler.handleError(resp, th);
                                    else{
                                          logger.info("no default errorHandler for this invoke process, abort!!");
                                    }
                              }else{
                              // 执行processor级的ErrorHandler; 
                              logger.info("run processor errorHandler and continue");
                              processorerrorHandler.handleError(resp, th);
                        }
                  } else {
                  logger.info("run Command Errorhandler and continue");
                  //                  执行Component级的ErrorHandler; 
                  errorHandler.handleError(resp, th);
            }
      }
}
logger.info(" SequenceProcessor 流程结束 -->");
}
}


在service中发生了异常有3个地方可以做切入点来做处理。Command级别,service级别和全局的错误处理器。如果在 command中发生异常,首先查找Command级别的错误处理器,找不到则找service级别的错误处理器,再找不到就找全局的错误处理器,什么也 没有找到异常则继续抛下去一直到客户端。如下面配置文件所示: 

<bean id="activity2"
class="org.artemis.workflow.command.Activity2">
<property name="errorHandler">
<ref bean="defaultErrorHandler" />
</property>
</bean>
<!-- error handler -->
<bean id="defaultErrorHandler"
class="com.gsta.eshore.framework.jcf.JCFErrorHandler" />


在activity2中发生异常就会查找defaultErrorHandler来做相应的处理。 

public class JCFErrorHandler implements ErrorHandler {
      private String beanName;
      private static Logger logger=Logger.getLogger(JCFErrorHandler.class);
      public void handleError(Response resp, Throwable th) throws Exception{
            if (th instanceof ClientException) {
                  logger.error("JCFErrorHandler is dealing with ClientException errorCode is "+((ClientException)th).getErrorCode(),th);
                  resp.setReturnCode(Response.APPLICATION_LEVEL_ERROR);
                  resp.getState().setErrCode(ErrorCode.BUSINESS_ERROR);
                  throw (ClientException)th;
            }
            else if (th instanceof GoOnException) {
                  logger.error("JCFErrorHandler is dealing with GoOnException", th);
            } else if(th instanceof JCFException){
                  logger.error("JCFErrorHandler is dealing with JCFException errorCode is "+((JCFException)th).getErrorCode(),th);
                  resp.setReturnCode(Response.APPLICATION_LEVEL_ERROR);
                  resp.getState().setErrCode(ErrorCode.JCF_ERROR);
                  throw (JCFException)th;
            } else if(th instanceof RemoteException){
                  logger.error("JCFErrorHandler is dealing with RemoteException",th);
                  resp.setReturnCode(Response.SYSTEM_LEVEL_ERROR);
                  resp.getState().setErrCode(ErrorCode.SYSTEM_ERROR);
                  throw (RemoteException)th;
            } else if(th instanceof EJBException){
                  logger.error("JCFErrorHandler is dealing with EJBException",th);
                  resp.setReturnCode(Response.SYSTEM_LEVEL_ERROR);
                  resp.getState().setErrCode(ErrorCode.CALL_EJB_ERROR);
                  throw (EJBException)th;
            } else if(th instanceof NullPointerException){
                  logger.error("JCFErrorHandler is dealing with RemoteException",th);
                  resp.setReturnCode(Response.APPLICATION_LEVEL_ERROR);
                  resp.getState().setErrCode(ErrorCode.NULLPOINT_ERROR);
                  throw (NullPointerException)th;
            }
            else{
                  logger.error("JCFErrorHandler is dealing with Exception",th);
                  resp.setReturnCode(Response.APPLICATION_LEVEL_ERROR);
                  resp.getState().setErrCode(ErrorCode.SYSTEM_ERROR);
                  if(th instanceof Exception)
                  throw (Exception)th;
            }
      }
      public void setBeanName(String beanName) {
            this.beanName = beanName;
      }
}


可以为每一个command或者service定制不同的错误处理器。针对不同的异常来设置不同的errorCode,同时后端的异常不会影响到客户端的操作。 
   总结:把异常处理抽取出来



--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论