系统中的异常可以分为我们能预知的异常和未知的系统异常,对于我们能预知的异常如空值判断,用户名错误,密码错误等异常我们需要返回客户端,对于系统内部异常如SQL语法错误,参数格式转换错误等需要统一包装成友好的提示后再返回客户端,否则用户也看不懂系统内部的异常
方案是可以自定义异常来封装我们能够预知的异常,和系统未知的异常做一个区分,自定义异常如下:
//自定义一个运行时异常
public class MyException extends RuntimeException {
public MyException(String message){
super(message);
}
}
使用自定义异常:
if(StringUitls.isNull(username)){
throw new MyException(“用户名不可为空哦”);
}
在控制器层捕获不同的异常:
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
public JSONResult delete(@PathVariable("id") Long id){
try {
tenantService.deleteById(id);
return JSONResult.success();
} catch (MyException e) { //自定义异常,message直接返回
e.printStackTrace();
return JSONResult.error(e.getMessage());
} catch (Exception e) { //未知异常 ,包装成友好提示返回
e.printStackTrace();
return JSONResult.error("系统异常啦,请联系管理员");
}
}
问题:
这样一来,controller中需要写大量重复的try{}catch() 代码
可以抽取工具类进行数据判断,然后抛出异常,即可以把
if(StringUitls.isNull(username)){
throw new GlobalException(“用户名不可为空哦”);
}
抽成工具类:如:MyTools
package cn.itsource.hrm.utils;
import cn.itsource.hrm.exception.MyException;
import org.springframework.util.StringUtils;
//工具类
public class MyTools {
/**
* 如果入参是空的话,那就抛出异常
* @param obj 需要校验的参数
* @param message 抛出的错误提示信息
*/
public static void isBlank(Object obj,String message){
if(null == obj){
throw new MyException(message);
}
//进行类型判断
if(obj instanceof String){
String objStr = String.valueOf(obj);
if(StringUtils.isEmpty(objStr)){
throw new MyException(message);
}
}
}
}
这样以后就这样使用:
MyTools.isBlank(tenant.getCompanyName(),"公司名称不可为空");
我们可以吧controller中大量重复的try{}代码抽取到专门的类中进行处理:
package cn.itsource.hrm.exception;
import cn.itsource.hrm.result.JSONResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理工具类
*/
@RestControllerAdvice //是对Controller进行增强的
public class GlobalExceptionHandler {
//捕获并处理自定义异常
@ExceptionHandler(MyException.class)
public JSONResult MyException(MyException e){
return JSONResult.error(e.getMessage());
}
//捕获并处理算术异常
@ExceptionHandler(ArithmeticException.class)
public JSONResult methodArithmeticException(ArithmeticException e){
return JSONResult.error("算术异常");
}
/**
* 如果发生上面没有捕获的异常,那么统一走这个异常捕获,相当于是最大的一个范围
*/
@ExceptionHandler(Exception.class)
public JSONResult exceptionHandler(Exception e){
e.printStackTrace();
return JSONResult.error("系统异常,请稍后再试");
}
}
这里的 RestControllerAdvice + ExceptionHandler 注解可以拦截到异常,针对不同的异常做不同的拦截,然后做出不同的处理
在controller执行不报异常的时候就会返回正确的结果,如果出现异常,走GlobalExceptionHandler 异常拦截类进行处理
Controller的写法:
@RequestMapping(value="/entering",method= RequestMethod.POST)
public JSONResult entering(@RequestBody TenantEnteringDto dto){
tenantService.entering(dto);
return JSONResult.success();
}
不再考虑try{}-catch,非常方便
需要导入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>