(JAVA)异常处理

博客主要解决两个问题,一是操作失败返回信息无法区分具体错误,二是service和controller中异常捕获代码冗余。解决办法包括在Service方法先校验抛异常,用统一异常处理类捕获异常。还介绍了可预知和不可预知异常处理的模板及开发实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解决问题:
1、操作不成功仅向用户返回“错误代码,失败信息:操作失败”,无法区别具体的错误信息。
2、service方法在执行过程出现异常在哪捕获?在service中需要都加try/catch,如果在controller也需要添加
try/catch,代码冗余严重且不易维护。
解决办法:
1、在Service方法中的编码顺序是先校验判断,有问题则抛出具体的异常信息,最后执行具体的业务操作,返回成
功信息。
2、在统一异常处理类中去捕获异常,无需controller捕获异常,向用户返回统一规范的响应信息
模板:

public CmsPageResult add(CmsPage cmsPage){
//校验cmsPage是否为空
if(cmsPage == null){
//抛出异常,非法请求
//...
} /
/根据页面名称查询(页面名称已在mongodb创建了唯一索引)
CmsPage cmsPage1 =
cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(),
cmsPage.getSiteId(), cmsPage.getPageWebPath());
//校验页面是否存在,已存在则抛出异常
if(cmsPage1 !=null){
//抛出异常,已存在相同的页面名称
//...
} c
msPage.setPageId(null);//添加页面主键由spring data 自动生成
CmsPage save = cmsPageRepository.save(cmsPage);
//返回结果
CmsPageResult cmsPageResult = new CmsPageResult(CommonCode.SUCCESS,save);
return cmsPageResult;
}

根据这个图来实现异常处理
1、可预知异常处理
1.1在公共部分定义异常类型

package com.xuecheng.framework.exception;

import com.xuecheng.framework.model.response.ResultCode;

/**
 * 自定义异常
 */
public class CustomException extends RuntimeException{

    //错误代码
    private ResultCode resultCode;

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

1.2定义异常抛出类

package com.xuecheng.framework.exception;


import com.xuecheng.framework.model.response.ResultCode;

public class ExceptionCast {

    //使用此静态方法抛出自定义异常
    public  static  void cast(ResultCode resultCode){
        throw  new CustomException(resultCode);
    }
}

1.3定义异常捕获类
使用 @ControllerAdvice和@ExceptionHandler注解来捕获指定类型的异常

@ControllerAdvice
publicclassExceptionCatch{
privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(ExceptionCatch.class);
//捕获CustomException异常
@ExceptionHandler(CustomException.class)
@ResponseBody
publicResponseResultcustomException(CustomExceptione){
LOGGER.error("catchexception:{}\r\nexception:",e.getMessage(),e);ResultCoderesultCode=e.getResultCode();
ResponseResultresponseResult=newResponseResult(resultCode);
returnresponseResult;
}
}

1.4定义错误代码
每个业务操作的异常使用异常代码去标识

packagecom.xuecheng.framework.domain.cms.response;
importcom.xuecheng.framework.model.response.ResultCode;importlombok.ToString;

@ToString
publicenumCmsCodeimplementsResultCode{
CMS_ADDPAGE_EXISTS(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;
}
}

2、启动工程,扫描到异常捕获的类ExceptionCatch
在springBoot的启动类中添加
@ComponentScan(basePackages=“com.xuecheng.framework”)//扫描common工程下的类
在这里插入图片描述
2、不可预知异常处理
2.1使用postman测试添加页面,不输入cmsPost信息,提交,报错信息如下

在这里插入图片描述
2.2 异常捕获方法
针对上边的问题其解决方案是:
1、我们在map中配置HttpMessageNotReadableException和错误代码。
2、在异常捕获类中对Exception异常进行捕获,并从map中获取异常类型对应的错误代码,如果存在错误代码则返
回此错误,否则统一返回99999错误。
具体的开发实现如下:
1、在通用错误代码类CommCode中配置非法参数异常

INVALID_PARAM(false,10003,"非法参数!"),

2、在异常捕获类中配置 HttpMessageNotReadableException 为非法参数异常。
异常捕获类代码如下:

/**
* @author Administrator
* @version 1.0
* @create 2018‐06‐11 17:16
**/
@ControllerAdvice
public class ExceptionCatch {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
//使用EXCEPTIONS存放异常类型和错误代码的映射,ImmutableMap的特点的一旦创建不可改变,并且线程安全
private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
//使用builder来构建一个异常类型和错误代码的异常
protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder =
ImmutableMap.builder();
//捕获Exception异常
@ResponseBody
@ExceptionHandler(Exception.class)
public ResponseResult exception(Exception e) {
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
if(EXCEPTIONS == null)
EXCEPTIONS = builder.build();
final ResultCode resultCode = EXCEPTIONS.get(e.getClass());
final ResponseResult responseResult;
if (resultCode != null) {
responseResult = new ResponseResult(resultCode);
} else {
responseResult = new ResponseResult(CommonCode.SERVER_ERROR);
} r
eturn responseResult;
} /
/捕获 CustomException异常
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult customException(CustomException e) {
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
ResultCode resultCode = e.getResultCode();
ResponseResult responseResult = new ResponseResult(resultCode);
return responseResult;
}
static{
//在这里加入一些基础的异常类型判断
builder.put(HttpMessageNotReadableException.class,CommonCode.INVALIDPARAM);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值