您的位置:首页 > 其它

关于异常的一些使用心得

2017-08-19 15:38 555 查看

起源

今天发现一个很奇怪的现象,程序中间错误了,但是却没有报错,我在外面的写的关于异常的处理代码也没有生效,程序就这样中断了,这个影响很严重的,理想情况下,不管这个过程中出现了什么错误,都会返回一个值给客户端,但现在是程序就这样中断了,客户端就会很疑惑,但我突然恍然大悟,原来是异常我没有抛出,故此,对异常使用的一些心得记录一下。

过程

首先说道异常的使用,其实就三种:

 throws Exception
 throw e
 try catch
那么,他们都在哪些场景进行使用呢?
throws Exception用于方法,只要在方法后面写上他,当这个方法出现异常时,该方法就会将该异常往调用这个方法的对象传递,这个上层就能破获到这个异常,进而可以写自己的逻辑来处理
throw e是抛出具体某一个异常,而他一般用于这样一个场景:这个方法里当出现某些异常时,自己进行相应处理,是程序正常进行下去,但当出现未知的异常时,就要将其抛给上层
try catch用于写处理异常的逻辑

那么,以上三种的使用,能玩出什么花样呢?
首先说一种场景,一般项目应该都会有一个错误日志系统吧,当某个api出现错误时,就将错误日志记录下来,而且返回给客户端一个值,告诉客户端程序出现错误了,这样,客户端就会作相应的出来来告诉用户,这样可以保证,不管出现什么,这个过程都能够结束,而不会中断。

那么,怎么做到的呢?

我用一个项目来说明,这个项目使用的是SSM框架,使用了部分rest的风格的api设计思路

//首页数据
@RequestMapping(value="/main",method=RequestMethod.POST)
public List<McMain> mcMain(String mainCode,String date){
System.out.println(mainCode+" "+date);
try {
if (mainCode!=null && date!=null) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
return baseInfoSer.mcMain(mainCode,sdf.parse(date));
}
} catch (Exception e) {
e.printStackTrace();
mail.addMail(new MailModel(MailManager.MAIL_ZS, MailManager.MAIL_HGH, Trans.strToHtml(e.getMessage()), MailManager.TITLE));
return new ArrayList<McMain>();
}
return new ArrayList<McMain>();
}

这个是restController的一个方法,是一个api接口,首先用try catch将主体部分包起来,并在异常处理部分写上日志相关代码(我使用的是邮件通知,关于邮件通知错误日志的设计可以看我之前的文章),以及返回给客户端一个值。

public List<McMain> mcMain(String mainCode,Date date) throws Exception {
List<BaseMain> mains=baseMainMapper.selectByMainCode(mainCode, date);
List<BaseMain> mains2=new ArrayList<>();
List<McMain> list2=new ArrayList<McMain>();
//调整顺序,让主站点在前
for (BaseMain m : mains) {
if (m.getCode().equals(m.getMainCode())) {
mains2.add(m);
break;
}
}
for (BaseMain m : mains) {
if (!m.getCode().equals(m.getMainCode())) {
mains2.add(m);
}
}
for (BaseMain bm : mains2) {
if (bm==null) {
break;
}
System.out.println(bm.getId());
BaseReceiveMonth brm=baseReceiveMonthMapper.selectByPrimaryKey(bm.getId());
BaseReceiveDay brd=baseReceiveDayMapper.selectByCodeAndTime(bm.getCode(), date);
List<BaseReceiveMonth> brms=baseReceiveMonthMapper.obtainByMonth(bm.getCode(), DateTimeHelper.getBefore8Month(date), date);
List<BaseReceiveMonth> brmsYear=baseReceiveMonthMapper.obtainByYear(bm.getCode(), DateTimeHelper.getBefore8Year(date), date);
List<BaseReceiveDay> brmsDay=baseReceiveDayMapper.obtainByDay(bm.getCode(), DateTimeHelper.getBefore8Year(date), date);

List<Line> goodsMonthLine=new ArrayList<Line>();
List<Line> weightMonthLine=new ArrayList<Line>();
List<Line> goodsWeightMonthLine=new ArrayList<Line>();
List<Line> incomeMonthLine=new ArrayList<Line>();
List<Line> incomeWeightMonthLine=new ArrayList<Line>();
List<Line> incomeGoodsMonthLine=new ArrayList<Line>();

List<Line> goodsYearLine=new ArrayList<Line>();
List<Line> weightYearLine=new ArrayList<Line>();
List<Line> goodsWeightYearLine=new ArrayList<Line>();
List<Line> incomeYearLine=new ArrayList<Line>();
List<Line> incomeWeightYearLine=new ArrayList<Line>();
List<Line> incomeGoodsYearLine=new ArrayList<Line>();

List<Line> goodsDayLine=new ArrayList<Line>();
List<Line> weightDayLine=new ArrayList<Line>();
List<Line> goodsWeightDayLine=new ArrayList<Line>();
List<Line> incomeDayLine=new ArrayList<Line>();
List<Line> incomeWeightDayLine=new ArrayList<Line>();
List<Line> incomeGoodsDayLine=new ArrayList<Line>();

SimpleDateFormat sdfYear=new SimpleDateFormat("yyyy");
SimpleDateFormat sdf=new SimpleDateFormat("yy/MM");
SimpleDateFormat sdfDay=new SimpleDateFormat("MM/dd");

for (int i = 0; i < 8; i++) {
Date datetmp=DateTimeHelper.getBefore8Month(date);
Calendar calendar=Calendar.getInstance();
calendar.setTime(datetmp);
calendar.add(Calendar.MONTH, i);
boolean isHave=false;//是否有值的标志
BaseReceiveMonth brmtmp=null;
for (BaseReceiveMonth brm2 : brms) {
if (sdf.format(brm2.getMonth()).equals(sdf.format(calendar.getTime()))) {
isHave=true;
brmtmp=brm2;
break;
}
}
if (isHave) {
goodsMonthLine.add(new Line(sdf.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getGoods())));
weightMonthLine.add(new Line(sdf.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getWeight())));
goodsWeightMonthLine.add(new Line(sdf.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getGoodsWeight())));
incomeMonthLine.add(new Line(sdf.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getIncome())));
incomeWeightMonthLine.add(new Line(sdf.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getIncomeWeight())));
incomeGoodsMonthLine.add(new Line(sdf.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getIncomeGoods())));
}else{
goodsMonthLine.add(new Line(sdf.format(calendar.getTime()), new BigDecimal(0)));
weightMonthLine.add(new Line(sdf.format(calendar.getTime()), new BigDecimal(0)));
goodsWeightMonthLine.add(new Line(sdf.format(calendar.getTime()), new BigDecimal(0)));
incomeMonthLine.add(new Line(sdf.format(calendar.getTime()), new BigDecimal(0)));
incomeWeightMonthLine.add(new Line(sdf.format(calendar.getTime()), new BigDecimal(0)));
incomeGoodsMonthLine.add(new Line(sdf.format(calendar.getTime()), new BigDecimal(0)));
}
}

for (int i = 0; i < 8; i++) {
Date datetmp=DateTimeHelper.getBefore8Year(date);
Calendar calendar=Calendar.getInstance();
calendar.setTime(datetmp);
calendar.add(Calendar.YEAR, i);
boolean isHave=false;//是否有值的标志
BaseReceiveMonth brmtmp=null;
for (BaseReceiveMonth brm2 : brmsYear) {
if (sdfYear.format(brm2.getMonth()).equals(sdfYear.format(calendar.getTime()))) {
isHave=true;
brmtmp=brm2;
break;
}
}
if (isHave) {
goodsYearLine.add(new Line(sdfYear.format(brmtm
4000
p.getMonth()), Trans.bigToBig0(brmtmp.getGoods())));
weightYearLine.add(new Line(sdfYear.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getWeight())));
goodsWeightYearLine.add(new Line(sdfYear.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getGoodsWeight())));
incomeYearLine.add(new Line(sdfYear.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getIncome())));
incomeWeightYearLine.add(new Line(sdfYear.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getIncomeWeight())));
incomeGoodsYearLine.add(new Line(sdfYear.format(brmtmp.getMonth()), Trans.bigToBig0(brmtmp.getIncomeGoods())));
}else{
goodsYearLine.add(new Line(sdfYear.format(calendar.getTime()), new BigDecimal(0)));
weightYearLine.add(new Line(sdfYear.format(calendar.getTime()), new BigDecimal(0)));
goodsWeightYearLine.add(new Line(sdfYear.format(calendar.getTime()), new BigDecimal(0)));
incomeYearLine.add(new Line(sdfYear.format(calendar.getTime()), new BigDecimal(0)));
incomeWeightYearLine.add(new Line(sdfYear.format(calendar.getTime()), new BigDecimal(0)));
incomeGoodsYearLine.add(new Line(sdfYear.format(calendar.getTime()), new BigDecimal(0)));
}
}

for (int i = 0; i < 8; i++) {
Date datetmp=DateTimeHelper.getBefore8Day(date);
Calendar calendar=Calendar.getInstance();
calendar.setTime(datetmp);
calendar.add(Calendar.DAY_OF_MONTH, i);
boolean isHave=false;//是否有值的标志
BaseReceiveDay brmtmp=null;
for (BaseReceiveDay brm2 : brmsDay) {
if (sdfDay.format(brm2.getTime()).equals(sdfDay.format(calendar.getTime()))) {
isHave=true;
brmtmp=brm2;
break;
}
}
if (isHave) {
goodsDayLine.add(new Line(sdfDay.format(brmtmp.getTime()), Trans.bigToBig0(brmtmp.getGoods())));
weightDayLine.add(new Line(sdfDay.format(brmtmp.getTime()), Trans.bigToBig0(brmtmp.getWeight())));
goodsWeightDayLine.add(new Line(sdfDay.format(brmtmp.getTime()), Trans.bigToBig0(brmtmp.getGoodsWeight())));
incomeDayLine.add(new Line(sdfDay.format(brmtmp.getTime()), Trans.bigToBig0(brmtmp.getIncome())));
incomeWeightDayLine.add(new Line(sdfDay.format(brmtmp.getTime()), Trans.bigToBig0(brmtmp.getIncomeWeight())));
incomeGoodsDayLine.add(new Line(sdfDay.format(brmtmp.getTime()), Trans.bigToBig0(brmtmp.getIncomeGoods())));
}else{
goodsDayLine.add(new Line(sdfDay.format(calendar.getTime()), new BigDecimal(0)));
weightDayLine.add(new Line(sdfDay.format(calendar.getTime()), new BigDecimal(0)));
goodsWeightDayLine.add(new Line(sdfDay.format(calendar.getTime()), new BigDecimal(0)));
incomeDayLine.add(new Line(sdfDay.format(calendar.getTime()), new BigDecimal(0)));
incomeWeightDayLine.add(new Line(sdfDay.format(calendar.getTime()), new BigDecimal(0)));
incomeGoodsDayLine.add(new Line(sdfDay.format(calendar.getTime()), new BigDecimal(0)));
}
}

McMain mcMain=new McMain(bm.getId(),bm.getPoint(), bm.getCode(), brm==null?new BigDecimal(0):brm.getGoods(),
brm==null?new BigDecimal(0):brm.getWeight(), brm==null?new BigDecimal(0):brm.getGoodsWeight(),
brm==null?new BigDecimal(0):brm.getIncome(), brm==null?new BigDecimal(0):brm.getIncomeWeight(),
brm==null?new BigDecimal(0):brm.getIncomeGoods(),
goodsMonthLine, weightMonthLine, goodsWeightMonthLine, incomeMonthLine, incomeWeightMonthLine, incomeGoodsMonthLine,
brd==null?new BigDecimal(0):brd.getGoods(),brd==null?new BigDecimal(0):brd.getWeight(),brd==null?new BigDecimal(0):brd.getGoodsWeight(),
brd==null?new BigDecimal(0):brd.getIncome(),brd==null?new BigDecimal(0):brd.getIncomeWeight(),brd==null?new BigDecimal(0):brd.getIncomeGoods(),
goodsDayLine,weightDayLine,goodsWeightDayLine,incomeDayLine,incomeWeightDayLine,incomeGoodsDayLine,
goodsYearLine,weightYearLine,goodsWeightYearLine,incomeYearLine,incomeWeightYearLine,incomeGoodsYearLine);
list2.add(mcMain);
}
return list2;
}
然后在service的方法一定要记得使用throws Exception将异常网上抛,这样controller层才能收到。

public static Date TransToDate(String str) throws Exception{
if(str!=null && !str.trim().equals("")){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd");
try {
Date date = sdf.parse(str);
return date;
} catch (ParseException e) {
try {
Date date = sdf2.parse(str);
return date;
} catch (Exception e2) {
e.printStackTrace();
log.error("字符串转Date类型失败,错误字符转为:"+str);
throw e2;
}
}
}else{
return null;
}
}
这个是service层使用到的一个方法,这里我只是举个例子,所有的方法都要按照这样思路处理,这个方法是将字符串转时间,首先考虑到字符串的格式,所以自己处理部分可能出现的异常,最后将未知的异常抛出(throw e2),当然方法名上也要记得写throws Exception。

结论

好啦,只要按照这种思路,就可以让你的程序十分健壮。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  异常 Exception