SpringBoot自定义异常捕获器-像这种微服务的项目全局异常捕获一般都放在common下
状态码
-
ResultCode接口
package com.xuecheng.framework.model.response; /** * 10000-- 通用错误代码 * 22000-- 媒资错误代码 * 23000-- 用户中心错误代码 * 24000-- cms错误代码 * 25000-- 文件系统 */ public interface ResultCode { //操作是否成功,true为成功,false操作失败 boolean success(); //操作代码 int code(); //提示信息 String message(); }
-
Response 接口
package com.xuecheng.framework.model.response; /** * */ public interface Response { public static final boolean SUCCESS = true; public static final int SUCCESS_CODE = 10000; } ```
-
ResponseResult 类
package com.xuecheng.framework.model.response; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; /** * */ @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); } }
-
CommonCode 状态码枚举
package com.xuecheng.framework.model.response; import lombok.ToString; /** * @Author: mrt. * @Description: * @Date:Created in 2018/1/24 18:33. * @Modified By: */ @ToString public enum CommonCode implements ResultCode{ SUCCESS(true,10000,"操作成功!"), FAIL(false,11111,"操作失败!"), UNAUTHENTICATED(false,10001,"此操作需要登陆系统!"), UNAUTHORISE(false,10002,"权限不足,无权操作!"), SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!"), INVALID_PARAMS(false,10003,"非法参数!"); // private static ImmutableMap<Integer, CommonCode> codes ; //操作是否成功 boolean success; //操作代码 int code; //提示信息 String message; private CommonCode(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; } }
-
CmsCode 状态枚举
package com.xuecheng.framework.domain.cms.response; import com.xuecheng.framework.model.response.ResultCode; import lombok.ToString; @ToString public enum CmsCode implements ResultCode { CMS_ADDPAGE_EXISTSNAME(false, 24001, "页面名称已存在!"), CMS_GENERATEHTML_DATAURLISNULL(false, 24002, "从页面信息中找不到获取数据的url!"), CMS_GENERATEHTML_DATAISNULL(false, 24003, "根据页面的数据url获取不到数据!"), CMS_GENERATEHTML_TEMPLATEISNULL(false, 24004, "页面模板为空!"), CMS_GENERATEHTML_HTMLISNULL(false, 24005, "生成的静态html为空!"), CMS_GENERATEHTML_SAVEHTMLERROR(false, 24005, "保存静态html出错!"), CMS_PAGE_NOTEXISTS(false, 24006, "页面不存在"), CMS_COURSE_PERVIEWISNULL(false, 24007, "预览页面为空!"); //操作代码 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; } }
异常类
-
CustomException
package com.xuecheng.framework.exception; import com.xuecheng.framework.model.response.ResultCode; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; /** * @Author: 潇哥 * @DateTime: 2020/10/29 下午2:21 * @Description: 自定义异常类 */ @Getter @NoArgsConstructor @AllArgsConstructor public class CustomException extends RuntimeException { private ResultCode resultCode; }
-
ExceptionCast
package com.xuecheng.framework.exception; import com.xuecheng.framework.model.response.ResultCode; /** * @Author: 潇哥 * @DateTime: 2020/10/29 下午2:22 * @Description: 封装自定义异常类 */ public class ExceptionCast { /** * 封装自定义异常 * @param resultCode */ public static void cast(ResultCode resultCode) { throw new CustomException(resultCode); } }
-
ExceptionCatch-----(重点: 捕获异常)
package com.xuecheng.framework.exception; import com.google.common.collect.ImmutableMap; import com.xuecheng.framework.model.response.CommonCode; import com.xuecheng.framework.model.response.ResponseResult; import com.xuecheng.framework.model.response.ResultCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.HttpMediaTypeNotSupportedException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * @Author: 潇哥 * @DateTime: 2020/10/29 下午2:23 * @Description: 捕获自定义异常类 */ @ControllerAdvice // 控制器增强 public class ExceptionCatch { private final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class); // 定义map, 配置异常类型所对应的错误代码 private static ImmutableMap<Class<? extends Throwable>, ResultCode> EXCEPTIONS; // 定义map的builder对象, 去构建ImmutableMap private static ImmutableMap.Builder<Class<? extends Throwable>, ResultCode> builder = ImmutableMap.builder(); /** * 捕获CustomException此类异常 * @param e * @return */ @ResponseBody @ExceptionHandler(CustomException.class) public ResponseResult customException(CustomException e) { LOGGER.error("操作失败: {}", e.getMessage()); return new ResponseResult(e.getResultCode()); } /** * 捕获Exception此类异常 * @param e * @return */ @ResponseBody @ExceptionHandler(Exception.class) public ResponseResult exception(Exception e) { LOGGER.error("操作失败: {}", e.getMessage()); if (EXCEPTIONS == null) { // EXCEPTIONS构建成功 EXCEPTIONS = builder.build(); } // 从EXCEPTIONS中找到异常类型所对应的错误代码, 如果找到了将错误代码响应给用户, 如果找不到给用户响应99999异常 ResultCode resultCode = EXCEPTIONS.get(e.getClass()); // 返回异常信息 if (resultCode != null) { return new ResponseResult(resultCode); } return new ResponseResult(CommonCode.SERVER_ERROR); } static { // 定义异常类型所对应的错误代码 builder.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAMS); builder.put(HttpMediaTypeNotSupportedException.class, CommonCode.INVALID_PARAMS); } }
Service层—只需要调用抛出的异常
-
使用ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME);抛出异常给ExceptionCatch类捕获
/** * 新增页面 * @param cmsPage * @return */ @Override public CmsPageResult add(CmsPage cmsPage) { // 根据页面名称-站点id-页面路径查询页面 CmsPage page = cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(), cmsPage.getSiteId(), cmsPage.getPageWebPath()); // 如果页面存在, 返回错误状态码 if (page != null) { ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME); } // 不存在添加进数据库 cmsPage.setPageId(null); // 必须设置为空, 让mongodb来创建id, 这样id才能唯一 cmsPageRepository.save(cmsPage); return new CmsPageResult(CommonCode.SUCCESS, cmsPage); }
启动类
-
ManageCmsApplication-------(重点–扫描捕获异常类的包)
package com.xuecheng.manage_cms; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; /** * @Author: 潇哥 * @DateTime: 2020/10/16 下午11:13 * @Description: TODO */ // 扫描该包同级或以下的所有包 @SpringBootApplication // 扫描实体类 @EntityScan("com.xuecheng.framework.domain.cms") // 扫描接口 @ComponentScan(basePackages = {"com.xuecheng.api"}) // 扫描common包下的类 **异常类放在common包下所以要扫描** @ComponentScan(basePackages = {"com.xuecheng.framework"}) // 扫描本项目下的所有类, 不写也行, 我这里写的原因是方便别人看好维护 @ComponentScan(basePackages = {"com.xuecheng.manage_cms"}) public class ManageCmsApplication { public static void main(String[] args) { SpringApplication.run(ManageCmsApplication.class, args); } }