010中提到了serivce层抛出异常,然后由Action层去捕获异常去处理,之前的写法是用java 自带的Exception,这样很繁琐的,而且,使用原始的Exception中的message不够用,需要自定义一个ExceptionResultInfo异常类解决信息不足的问题。
所以我们这里编写一个自定义的异常类,统一异常处理。
Java中进行异常处理:
一类是可预知的异常,程序员在编码时,主动抛出的异常,为了给用户操作提示,提前检查代码中可能存在异常。
通过开发中,采用自定义的异常类,每个异常类表示每一类异常信息。类需要继承Exception类。
本系统采用统一异常类,提供一个属性标识异常类。
另一类是不可预知异常,就是runtimeException异常,通过提高代码编写质量来避免此类异常,也可通过后期测试 人员进行系统功能测试对runtime异常进行避免。
我们主要对可预知的异常处理进行处理:
我们先要定义一个自己的异常类:
package yycg.base.process.result; /** * 自定义系统异常类 */ public class ExceptionResultInfo extends Exception { // 系统统一使用的结果类,包括了 提示信息类型和信息内容 private ResultInfo resultInfo; public ExceptionResultInfo(ResultInfo resultInfo) { super(resultInfo.getMessage()); this.resultInfo = resultInfo; } public ResultInfo getResultInfo() { return resultInfo; } public void setResultInfo(ResultInfo resultInfo) { this.resultInfo = resultInfo; } }
我们看一下ResultInfo 这个类,包含了异常的信息。
package yycg.base.process.result; import java.util.HashMap; import java.util.List; import java.util.Map; import yycg.util.ResourcesUtil; /** * 系统提示信息封装类 * @author mrt * */ public class ResultInfo { public static final int TYPE_RESULT_FAIL = 0;//失败 public static final int TYPE_RESULT_SUCCESS = 1;//成功 public static final int TYPE_RESULT_WARN = 2;//警告 public static final int TYPE_RESULT_INFO = 3;//提示信息 public ResultInfo(){} /** * 消息提示类型 */ private int type; /** * 提示代码 */ private int messageCode; /** * 提示信息 */ private String message; /** * 提示信息明细列表 */ private List<ResultInfo> details; public List<ResultInfo> getDetails() { return details; } public void setDetails(List<ResultInfo> details) { this.details = details; } /** * 提示消息对应操作的序号,方便用户查找问题,通常用于在批量提示信息中标识记录序号 */ private int index; /** * 提交后得到到业务数据信息从而返回给页面 */ private Map<String,Object> sysdata = new HashMap<String, Object>(); /** * 构造函数,根据提交信息代码messageCode获取提示信息 * @param MESSAGE */ public ResultInfo(final int type,int messageCode,String message){ this.type = type; this.messageCode = messageCode; this.message = message; } public int getMessageCode() { return messageCode; } public void setMessageCode(int messageCode) { this.messageCode = messageCode; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getType() { return type; } public void setType(int type) { this.type = type; } public boolean isSuccess(){ if(this.type == TYPE_RESULT_SUCCESS){ return true; } return false; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public Map<String, Object> getSysdata() { return sysdata; } public void setSysdata(Map<String, Object> sysdata) { this.sysdata = sysdata; } }
有了这两个类,我们就可以继续往下做了。在Service层里去抛出异常,然后在Action中去捕获异常。
我们修改userServiceimpl.java中的insertSysuser函数,把之前的用抛出Exction的做法改为统一的异常类来处理。
@Override public void insertSysuser(SysuserCustom sysuserCustom) throws Exception { //参数的校验 //通用的参数合法性校验 Sysuser sysuser=findSysuerByUserid(sysuserCustom.getUserid()); //如果不等于空,就是账号重复了。给出一个警告。 if(sysuser!=null) { //抛警告到Action,可以在Aciton中捕获这个异常。 //使用系统自定义的异常类 ResultInfo resultInfo=new ResultInfo();
//设置异常的类型:是正确的还是错误的. resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL); resultInfo.setMessage("是账号重复了"); throw new ExceptionResultInfo(resultInfo);//这里抛的就是我们自己定义的异常类了。 } //根据用户类型,输入单位名称必须存在对应的单位表中 String groupid=sysuserCustom.getGroupid();//用户类型 String sysmc=sysuserCustom.getSysmc();//单位名称 String userid=null; if(groupid.equals("1")||groupid.equals("2")) {//监督单位 //根据单位名称查询单位的信息。 Userjd userjd=this.findUserJdByMc(sysmc); if(userjd==null) { //使用系统自定义的异常类 ResultInfo resultInfo=new ResultInfo(); resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL); resultInfo.setMessage("单位名称输入错误"); throw new ExceptionResultInfo(resultInfo); } userid=userjd.getId(); } //卫生室 else if(groupid.equals("3")) { //根据单位名称查询单位的信息,查不到就报错 Useryy useryy=this.findUseryyByMc(sysmc); if(useryy==null) { //throw new Exception("单位名称输入错误"); //使用系统自定义的异常类 ResultInfo resultInfo=new ResultInfo(); resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL); resultInfo.setMessage("单位名称输入错误"); throw new ExceptionResultInfo(resultInfo); } userid=useryy.getId(); } else if(groupid.equals("4")){ Usergys usergys=this.findUsergesByMc(sysmc); if(usergys==null) { //throw new Exception("单位名称输入错误"); //使用系统自定义的异常类 ResultInfo resultInfo=new ResultInfo(); resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL); resultInfo.setMessage("单位名称输入错误"); throw new ExceptionResultInfo(resultInfo); } userid=usergys.getId(); } sysuserCustom.setId(UUIDBuild.getUUID()); sysuserCustom.setSysid(userid);//把用户表设置工作单位id //把数据插入到数据库 //刚开始的时候感到很奇怪,就是在SysuserMapper.xml中写着输入的参数是yycg.base.pojo.po.Sysuser //但是我这里输入的是sysuserCustom,明显不是Sysuser类型啊,其实是没有关系的,因为,这里的sysuserCustom //继承了Sysuser.所以Sysuser里面有的,在SysuserCustom里面都是有的的。 sysuserMapper.insert(sysuserCustom); }
接着修改Action层代码:之前的做法是在UserAction中返回Map类型的。这里改动很大。返回一个自己写的一个类。
//添加用户提交 //提交的结果要转json到页面 //提交表单的数据一律使用包装类,这里我们用的是SysuserQueryVo //在SysuserQueryVo中包装了SysuserCustom @RequestMapping("/addsysusersubmit") public @ResponseBody SubmitResultInfo addsysusersubmit(SysuserQueryVo sysuserQueryVo) throws Exception {//提示用户的信息。 /*String message="操作成功"; int type=0;//0表示成功,1表示失败 */ ResultInfo resultInfo=new ResultInfo(); resultInfo.setType(ResultInfo.TYPE_RESULT_SUCCESS);//默认是成功的,如果没有异常就把这个置于submitResultInfo,通过ResponseBody,转变为json返回到JSp页面。 resultInfo.setMessage("成功了"); SubmitResultInfo submitResultInfo=new SubmitResultInfo(resultInfo); try { //调用Service执行用户的添加。 userService.insertSysuser(sysuserQueryVo.getSysuserCustom()); } catch (Exception e) { e.printStackTrace(); /*message=e.getMessage(); type=1;//表示失败。 */ //这样的话就是系统的自定义异常 if(e instanceof ExceptionResultInfo) { //解析系统的自定义的异常, resultInfo=((ExceptionResultInfo) e).getResultInfo(); }else { //不属于系统自定义异常的话就是未知错误的异常,就是不可知的异常 //resultInfo=new ResultInfo(); resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL); resultInfo.setMessage("未知错误异常"); } } //将执行结果返回页面 submitResultInfo.setResultInfo(resultInfo); return submitResultInfo; }
接下来看一下SubmitResultInfo里面是什么?
package yycg.base.process.result; /** * 系统提交结果结果类型 * @author Thinkpad * */ public class SubmitResultInfo { public SubmitResultInfo(ResultInfo resultInfo){ this.resultInfo = resultInfo; } //操作结果信息 private ResultInfo resultInfo; public ResultInfo getResultInfo() { return resultInfo; } public void setResultInfo(ResultInfo resultInfo) { this.resultInfo = resultInfo; } }
当我们的Action把submitResultInfo返回后,所以在页面要统一使用一个方法解析json结果,我们看一下,jsp页面做了什么。
jsp执行的是jquerySubByFId('userform',sysusersave_callback,null,"json");所以当Action把json数据返回时,执行的回调函数是:sysusersave_callback
好!
这个函数里面就一句代码
function sysusersave(){
//准备使用jquery 提供的ajax Form提交方式
//将form的id传入,方法自动将form中的数据组成成key/value数据,通过ajax提交,提交方法类型为form中定义的method,
//使用ajax form提交时,不用指定url,url就是form中定义的action
//此种方式和原始的post方式差不多,只不过使用了ajax方式
//第一个参数:form的id
//第二个参数:sysusersave_callback是回调函数,sysusersave_callback当成一个方法的指针
//第三个参数:传入的参数, 可以为空
//第四个参数:dataType预期服务器返回的数据类型,这里action返回json
//根据form的id找到该form的action地址
jquerySubByFId('userform',sysusersave_callback,null,"json");
}
//ajax调用的回调函数,ajax请求完成调用此函数,传入的参数是action返回的结果
function sysusersave_callback(data){
message_alert(data);
}
就是 message_alert(data)对Action返回的JSON数据进行处理。
我们看一下 message_alert(data)里面的代码:
到这里就完成了统一异常类的处理。