1.定义异常类
public class GlobalException extends RuntimeException{//运行时异常
public GlobalException(){
super();
}
public GlobalException(String message){
super(message);
}
public GlobalException(String message,Throwable cause){
super(message,cause);
}
}
2.需要的地方抛异常
if(StringUtils.isBlank(dto.getTenant().getCompanyName())){
throw new GlobalException("机构名不能为空");
}
3.控制层异常检测
try{
tenantService.entering(dto);
return AjaxResult.me();
}
catch (GlobalException e){//可预估错误
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
}
catch (Exception e){//不可预估错误
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("内部错误,请联系管理员");
}
存在问题:可能需要写很多if去判断是否需要抛异常,同时也需要写很多catch
解决方案1.断言
实现
1.
public class ValidUtils {
public static void assertNotNull(Object obj,String message){
if(null==obj){
throw new GlobalException(message);
}
if(obj instanceof String){
String objStr = (String)obj;
if(objStr.length()==0){
throw new GlobalException(message);
}
}
}
}
2.需要异常判断的时候
ValidUtils.assertNotNull(dto.getTenant().getCompanyName(),"机构名不能空");
解决问题catch
方案:全局异常处理
1.引入spring-boot-starter-web依赖
2.创建工具类
@RestControllerAdvice //在controller前,后做一些事情
public class GlobalExceptinHandler {
//处理全局异常 处理GlobalException处理哪个异常,返回AjaxResult
@ExceptionHandler(GlobalException.class) //处理GlobalException
public AjaxResult globalExceptionHandler(GlobalException e){
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
}
@ExceptionHandler(Exception.class) //处理GlobalException
public AjaxResult ExceptionHandler(Exception e){
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("内部错误,请联系管理员");
}
}
3.控制层原来监听异常的地方,就可以不要try和catch了,直接如下,对比上面有的时候
tenantService.entering(dto);
return AjaxResult.me();
全局判空还是不好用,使用springmvc提供的JSR303规范
1.传参对象类添加注解
@Valid
private Tenant tenant;
@Valid
private Employee employee;
@NotNull(message = "套餐不能为空")
private Long mealId;
@NotEmpty(message = "重复输入密码不能为空")
private String comfirmPwd; 如果传的是对象,那么可以直接去对象里面加notnull,NotEmpty,要求传参不能为空,这样子外面就可以不加notnull,加 @Valid
2.控制层添加注解@Valid(表示这里使用异常处理)
@PostMapping("/entering")
public AjaxResult entering(@RequestBody @Valid TenantEnteringDto dto){
tenantService.entering(dto);
return AjaxResult.me();
}
全局实现(如果全局实现了,控制层就不需要加@Valid注解)
@RestControllerAdvice //在controller前,后做一些事情
public class GlobalExceptinHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public AjaxResult MethodArgumentNotValidException(MethodArgumentNotValidException e){
e.printStackTrace();
List<FieldError> fieldErrorList = e.getBindingResult().getFieldErrors();
StringBuffer stringBuffer = new StringBuffer();
fieldErrorList.forEach(error->{
String field = error.getField();
String message = error.getDefaultMessage();
stringBuffer.append(field).append(message).append(",");
});
return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
}
}
总结:对于比较简单的异常处理,直接使用JSR303进行处理,如果复杂的话就自定义异常使用断言来处理,当然,无论是哪种方式,都定义全局实现,达到控制层不用加try,catch的效果