基于Spring和hibernate的灵活的异常处理办法

在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,同时后端的异常不会影响到客户端的操作。
总结:把异常处理抽取出来,代码进一步简化。如果有什么疑问或者good idea欢迎给我发邮件:gmhwq@126.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSH2框架是结合了Spring3.2、Struts2.3.4和Hibernate4.2三个框架的一种开发模式。它的目标是将这三个框架的优势结合起来,实现更高效、更方便的开发方式。 首先,Spring框架作为SSH2的核心框架,提供了Spring IOC容器和AOP特性。Spring能够管理对象的生命周期,简化了大量的配置和代码。它还提供了声明式事务管理和面向切面编程能力,极大地简化了事务处理和异常处理。 其次,Struts2作为SSH2的MVC框架,提供了强大的请求处理和表单验证功能。它基于标签和表达式语言,可以直接将页面元素和后台数据进行绑定,大大减少了前端和后台开发的工作量。Struts2还支持拦截器,能够方便地进行权限控制和请求的预处理。 最后,Hibernate作为SSH2的ORM框架,提供了面向对象的数据库访问方式。Hibernate能够将Java对象和数据库表进行映射,并提供了强大的查询和缓存功能。使用Hibernate,开发者可以将精力集中在业务逻辑上,而不需要过多关注数据库操作的细节。 通过整合Spring、Struts2和Hibernate,SSH2框架能够极大地简化企业级应用的开发过程。开发者可以更专注于业务逻辑的设计和实现,而不需要关心框架的集成和配置。同时,SSH2框架还提供了良好的扩展性和灵活性,可以根据项目需求进行定制和拓展。 总而言之,SSH2框架是一种结合了Spring、Struts2和Hibernate的开发模式,通过整合三个框架的优势,提供了更高效、更方便的开发方式。它简化了项目的配置和集成,提高了开发效率,是开发企业级应用的优秀选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值