在处理异常的时候,一般都是dao层向上抛,抛到service层,service层也向上抛,抛到controller层,最终我们会采取在controller层进行捕获异常,进行响应。
1.首先定义一个自定义异常类,此处自定义异常类是通过 ResultCode 接口当属性进行定义的
package com.lxw.framework.exception;
import com.lxw.framework.model.response.ResultCode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author by houbing
* @date 2022/3/17 18:30
* @Classname TransactionServiceImpl 自定义异常
* @Description TODO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomException extends RuntimeException{
private ResultCode resultCode;
}
2、之后定义一个异常捕获类,在类上需要使用@ControllerAdvice 注解,他的作用是:统一捕获controller层异常。
定义捕获异常方法,在方法上要使用@ExceptionHandler注解,他的作用是:捕获异常,但是要注意的是:括号的类型要与参数类型一致,这样才能捕获自己定义的异常,或者未知异常,还需要在方法上加上@ResponseBody注解,作用是:捕获异常之后不进行页面跳转,把异常信息直接响应给前端
package com.lxw.framework.exception;
import com.lxw.framework.model.response.CommonCode;
import com.lxw.framework.model.response.ResponseResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author by houbing
* @date 2022/3/17 18:32
* @Classname CatchException
* @Description TODO
*/
@ControllerAdvice //统一捕获controller层异常
public class CatchException {
//捕获自定义异常
@ExceptionHandler(CustomException.class)//捕获 CustomException异常(括号的类型要与参数类型一致)
@ResponseBody//捕获异常之后不进行页面跳转,直接响应给前端
public ResponseResult catchCustomException(CustomException customException){
return new ResponseResult(customException.getResultCode());
}
//捕获未知异常
@ExceptionHandler(Throwable.class)
@ResponseBody
public ResponseResult catchException(Throwable throwable){
return new ResponseResult(CommonCode.SERVER_ERROR);
}
}
返回详细的位置异常信息,一般采用上述那种未知异常信息即可,不需要采用下述详细异常信息
package com.lxw.framework.exception;
import com.google.common.collect.ImmutableMap;
import com.lxw.framework.model.response.CommonCode;
import com.lxw.framework.model.response.ResponseResult;
import com.lxw.framework.model.response.ResultCode;
import com.mongodb.MongoSocketOpenException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author by houbing
* @date 2022/3/17 18:32
* @Classname CatchException
* @Description TODO
*/
@ControllerAdvice //统一捕获controller层异常
public class CatchException {
//捕获自定义异常
@ExceptionHandler(CustomException.class)//捕获 CustomException异常(括号的类型要与参数类型一致)
@ResponseBody//捕获异常之后不进行页面跳转,直接响应给前端
public ResponseResult catchCustomException(CustomException customException){
return new ResponseResult(customException.getResultCode());
}
/**
*
* @param throwable
* @return com.lxw.framework.model.response.ResponseResult
//捕获未知异常(一般情况下采取的是这种处理方式)
@ExceptionHandler(Throwable.class)
@ResponseBody
public ResponseResult catchException(Throwable throwable){
//捕捉到未知异常后抛出的信息
return new ResponseResult(CommonCode.SERVER_ERROR);
}*/
//使用MAP存放异常类型和错误代码的映射,ImmutableMap的特点的一旦创建不可改变,并且线程安全
private static ImmutableMap<Class<? extends RuntimeException>, ResultCode> MAP;
//使用builder来构建一个异常类型和错误代码的异常(充当中间容器,进行储存)
private static ImmutableMap.Builder<Class<? extends RuntimeException>, ResultCode> builder = ImmutableMap.builder();
static {
//将错误信息添加到builder中
builder.put(MongoSocketOpenException.class, CommonCode.COLLECTIONMONGODB);
builder.put(HttpMessageNotReadableException.class,CommonCode.HTTPMESSAGEFAIL);
}
//捕获未知异常(这里采取的是详细异常信息处理方式)
@ExceptionHandler(Throwable.class)
@ResponseBody
public ResponseResult catchException(Throwable throwable){
if(MAP == null){
//构建builder对象,并将builder对象中的异常信息储存到MAP中
MAP = builder.build();
}
//根据异常类型获取resultCode
ResultCode resultCode = MAP.get(throwable.getClass());
if(resultCode!=null){
return new ResponseResult(resultCode);
}else {
return new ResponseResult(CommonCode.SERVER_ERROR);
}
}
}
在要进行异常捕获的模块下,在启动类上,加上@ComponentScan(basePackages = "com.lxw.framework"),作用是:扫描此包下的注解,并进行加载