浏览 2453 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-06-12
在单元测试代码中: 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,同时后端的异常不会影响到客户端的操作。 总结:把异常处理抽取出来,代码进一步简化。如果有什么疑问或者good idea欢迎给我发邮件:gmhwq@126.com 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |