项目是基于公司内部的一个开发平台,对java基本的一些处理都封装好了, 异常处理也就变得尤为重要了。
在写代码的时候,我之前的宗旨是,不提示要try catch 一般不会去处理。 如果程序在正常情况下问题也不会出现错误, 可是在测试的过程中,发现了不少令人头疼问题。
方法抛出运行时的异常是不自动提示异常捕捉的,所以我在写代码的时候忽略了对这些异常处理。导致一系列非正常运行情况下总出现问题。
用一段代码详细的讲解。
try{
//获得用户ID
String userId=getUserInfo().getUserId();
String status=bean.getStatus();
//保存数据
if("1".equals(status)){ //保存
evectionExpenseFormService.doSave(bean,detailBean,userId);
}else if("2".equals(status)){ //提交
//提交流程处理
completeTaskResult=evectionExpenseFormService.doSubmit(bean,getUserInfo(),category,bean.getProcessinsId());
}
//返回id和申请编号,前台处理
setResult("result",bean.getId()+"&"+bean.getApplyNo()+"&"+JSONObject.fromObject(completeTaskResult));
} catch (SessionTimeoutException stex) {
//Session超时异常
log.error(stex);
//使用拦截器处理异常信息
//ALMOND_MVC_00006 是错误信息国际化的编码,会返回对应的错误提示信息
throw AmondException.ThrowAmondException("ALMOND_MVC_00006");
//如果不使用拦截器处理异常,可以通过这种方式把错误信息传到前台
//this.setErrorMessage("TOFT_MVC_00006");
//return RLOGIN;
} catch (SaveFormException savefex){
//保存表单数据异常
log.error(savefex);
throw AmondException.ThrowAmondException("ALMOND_MVC_00007");
} catch(UnexpectedRollbackException urex){
//保存表单数据异常 回滚异常
log.error(urex);
throw AmondException.ThrowAmondException("ALMOND_MVC_00008");
} catch (SubmitFormException subfex){
//提交表单数据异常
log.error(subfex);
throw AmondException.ThrowAmondException("ALMOND_MVC_00009");
} catch (JSONException jsonex){
//JSON异常
log.error(jsonex);
throw AmondException.ThrowAmondException("ALMOND_MVC_00010");
} catch (Exception ex){
log.error(ex);
this.setErrorMessage(ex.getMessage());
return ERROR;
}
上面代码中获取用户id会抛出自定义SessionTimeoutException异常,在保存数据的时候我把所有的异常汇总成自定义SaveFormException异常,提交数据的也把所有的异常汇总成自定义SubmitFormException异常。这样碰到异常就能准确的把错误提示信息传给前台进行alert。当然还有比较重要的一点,大家可能不是很明白这个自定义回滚异常,回滚异常是当程序碰到异常的时候触发回滚时抛出的异常。上段代码保存和提交我都用到了事务,碰到运行时异常就会触发回滚,比如对数据库执行的一些操作。 Json转换的时候也是抛出运行时的异常(RuntimeException),不try catch也不会提示的。刚开始我也这段代码的时候try catch都没用,因为都没报错,正常运行情况下也没有问题。 后来加的这些处理。
举个自定义异常的例子,这个是自定义SessionTimeoutException
public class SessionTimeoutException extends Exception{
/**
* @Fields serialVersionUID : TODO
*/
private static final long serialVersionUID = 5721686959716896576L;
public SessionTimeoutException(){
}
public SessionTimeoutException(Throwable cause){
super(cause);
}
public SessionTimeoutException(String message){
super(message);
}
}
如果程序中用到事务的处理,一定要特别注意,事务开始、事务提交、事务回滚要同时使用。不然很容易造成死锁。
例如:
try{
beginTransaction();//启用事务
// 当流程实例存在时,二次提交
if(processinstancesid != null && !"".equalsIgnoreCase(processinstancesid)) {
//处理
} else {//提交流程处理
}
commitTransaction();//提交事务
}catch(Exception ex){
rollbackTransaction();//事务回滚
throw new SubmitFormException(ex);
}
struts.xml配置文件跳转到错误页面的代码
<package name="finance" extend="toft-default" namespace="/finance"> <action name="individualFormList" class="finance.IndividualFormListAction"> <result name="success">/almond/finance/success.jsp</result> </action> </package>
extend 的action.xml配置文件
<package name="toft-default" namespace="default"> <result-types> <result-type name="jsp" class="com.mvc.result.supports.ServletResult" /> <result-type name="ajax" class="com.mvc.result.supports.AjaxResult" /> <result-type name="redirect" class="com.mvc.result.supports.RedirectResult" /> </result-types> <interceptors> <interceptor name="exceptionInterceptor" class="com.mvc.interceptor.supports.ExceptionInterceptor"> </interceptor> <interceptor-stack name="interceptor-stack"> <interceptor-ref name="exceptionInterceptor" /> </interceptor-stack> </interceptors> <global-results> <!-- failure 页面 --> <result name="failure">/almond/exception/failure.jsp</result> <!-- error 页面 --> <result name="error">/almond/exception/error.jsp</result> <!-- alert 页面 --> <result name="alert">/almond/exception/alert.jsp</result> <!-- message 页面 --> <result name="message">/almond/exception/message.jsp</result> </global-results> <default-interceptor-ref>interceptor-stack</default-interceptor-ref> <default-result-type>jsp</default-result-type> </package>
ExceptionInterceptor.java拦截器类中把错误提示信息设置到对象中。通过返回的类型封装错误信息处理,例如:<result-type name="ajax"
class="com.toft.mvc.result.supports.AjaxResult" />
用jsp设计异常信息页面,让错误信息一目了然。如果使用ajax调用后台抛出的错误信息,在ajax请求中加上
error: function(request, textStatus){ toft.unlockPage(); alert(request.responseText); }
就会把错误提示alert到页面上。