关于异常的一些使用心得

起源

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


过程

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

  1.  throws Exception
  2.  throw e
  3.  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(brmtmp.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。


结论

好啦,只要按照这种思路,就可以让你的程序十分健壮。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值