项目中的异常处理

项目中的异常处理

写在前面:
项目中经常遇到的异常处理一般分为两大类:可以预知的异常处理,不可预知的异常处理,本文针对于这两种异常处理给出具体的解决思路,如有问题,烦请斧正

可预知的异常
指的是在程序中根据业务需求或者是程序运行之前保证运行无误,提前对异常进行判断处理。一般返回的异常信息包括:执行结果标志(成功/失败)、错误码、错误提示信息。处理方案,看代码

不可预知的异常
指的是由框架抛出来的异常

首先定义一个interface,以便于扩展

/**
 *错误信息通用类
 */
public interface ResultCode {
    //操作是否成功,true为成功,false操作失败
    boolean success();
    //操作代码
    int code();
    //提示信息
    String message();
}

定义一个具体的类来实现interface

@ToString
public enum CmsCode implements ResultCode {
	//这里使用枚举类型,可以定义多种错误信息
    CMS_ADDPAGE_EXISTSNAME(false,24001,"页面名称已存在!")//操作代码
    boolean success;
    //操作代码
    int code;
    //提示信息
    String message;
    private CmsCode(boolean success, int code, String message){
        this.success = success;
        this.code = code;
        this.message = message;
    }

    @Override
    public boolean success() {
        return success;
    }

    @Override
    public int code() {
        return code;
    }

    @Override
    public String message() {
        return message;
    }
}

定义一个通用的异常捕获类

public class CustomException extends RuntimeException {

    private ResultCode resultCode;

    public CustomException(ResultCode resultCode){
        super("错误代码:"+resultCode.code()+"错误信息:"+resultCode.message());
        this.resultCode = resultCode;
    }

    public ResultCode getResultCode(){
        return this.resultCode;
    }
}

将异常捕获类进行封装使用

public class CastException {

    public static void cast(ResultCode resultCode){
        throw new CustomException(resultCode);
    }
}

对异常捕获类进行捕获
@ControllerAdvice:控制器增强注解
@ExceptionHandler(CustomException.class):异常捕获注解,该注解会将拦截指定的异常类信息,然后就可以进行处理
@ResponseBody:将捕获到的异常信息进行返回,主要是结合springmvc返回json字符串使用

@ControllerAdvice
public class CatchException {

    Logger logger = LoggerFactory.getLogger(CastException.class);

    //处理不可知异常,ImmutableMap的特点的一旦创建不可改变,并且线程安全
    private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
    //使用builder来构建一个异常类型和错误代码的异常
    protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();
    static{
        //在这里加入一些基础的异常类型判断
        builder.put(HttpMessageNotReadableException.class, CommonCode.INVALIDPARAM);
    }


    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseResult customException(CustomException e){
        logger.error("catch exception",e.getMessage(),e);
        ResultCode resultCode = e.getResultCode();
        return new ResponseResult(resultCode);
    }


    //处理可以预知的异常
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult Exception(Exception e){
        logger.error("catch exception",e.getMessage(),e);
        if(EXCEPTIONS == null){
        	//构建异常信息
            EXCEPTIONS = builder.build();
        }
        //从构建的异常信息中获取指定的异常
        ResultCode resultCode = EXCEPTIONS.get(e.getClass());
        if(resultCode!=null){
            return new ResponseResult(resultCode);
        }else{
            return new ResponseResult(CommonCode.SERVER_ERROR);
        }
    }
}
@Data
@ToString
@NoArgsConstructor
public class ResponseResult implements Response {

    //操作是否成功
    boolean success = SUCCESS;

    //操作代码
    int code = SUCCESS_CODE;

    //提示信息
    String message;

    public ResponseResult(ResultCode resultCode){
        this.success = resultCode.success();
        this.code = resultCode.code();
        this.message = resultCode.message();
    }

    public static ResponseResult SUCCESS(){
        return new ResponseResult(CommonCode.SUCCESS);
    }
    public static ResponseResult FAIL(){
        return new ResponseResult(CommonCode.FAIL);
    }

}
public interface Response {
    public static final boolean SUCCESS = true;
    public static final int SUCCESS_CODE = 10000;
}

在具体业务中的使用

 public CmsPageResult add(CmsPage cmsPage){
        //检验是否重复插入,根据页面名称,站点id,页面的访问路径
        CmsPage page = cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName()
                , cmsPage.getSiteId(), cmsPage.getPageWebPath());

        if(page != null){
            CastException.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME);
        }
		…… ……
}

注意:
如果是springboot微服务工程,异常处理类和微服务工程不在同一个module下,需要在启动类上进行扫描处理

@SpringBootApplication
//进行包扫描
@ComponentScan(basePackages = {"com.xuecheng.framework"})
public class ManageCmsApplication {
    public static void main(String[] args){
        SpringApplication.run(ManageCmsApplication.class);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43794897/article/details/85019904