精华内容
下载资源
问答
  • Java提供了一些通用异常,但是通常不能满足我们的需求,因此自定义异常在软件开发中成为不可或缺的一部分,此处提供了一个简单的通过枚举实现的自定义状态码。 代码详解 设计一个接口,接口定义了状态码,消息信息...

    背景

    Java提供了一些通用异常,但是通常不能满足我们的需求,因此自定义异常在软件开发中成为不可或缺的一部分,此处提供了一个简单的通过枚举实现的自定义状态码。

    代码详解

    设计一个接口,接口定义了状态码,消息信息以及获取方式

    public interface MExceptionEnum{
        /**
        * 获取状态码
        * @return 状态码
        * /
        public String getCode();
        
        /**
        * 获取提示信息
        * @return 提示信息
        * /
        public String getMessage();
    }
    

    设计枚举类,实现上述接口,定义了具体的异常信息和状态码,当有新的状态码时,只需要添加一条对应的信息即可

    public enum ExceptionEnum implements MExceptionEnum{
       //自定义的状态码
       DATABASE_EXCEPTION("2000","数据库连接异常"),
       MONITOR_EXCEPTION("2001","文件监控异常")//错误码
       public String code;
       //提示信息
       public String message;
    
       //构造函数
       ExceptionEnum(String code,String message){
          this.code = code;
          this.message = message;
       }
    
       //获取状态码
       public String getCode(){
          return code;
       }
       
       //获取提示信息
       public String getMessage(){
          return message;
       }
     
    }
    

    创建一个异常类,可在整个类中通用,根据不同得场景,抛出不同的异常信息

    //此处异常类得名字建议用项目名加上Exception,整个项目的通用异常
    public class MiException extends RuntimeException{
        private ExceptionEnum exceptionEnum;
        
        public MiException(ExceptionEnum exceptionEnum){
           this.exceptionEnum = exceptionEnum;
        }
    
        public ExceptionEnum getExceptionEnum(){
           return exceptionEnum;
       }
      
      //用来输出异常信息和状态码
       public void printException(MiException e){
          ExceptionEnum exceptionEnum = e.getExceptionEnum();
          System.out.println("异常代码:" + exceptionEnum.getCode() + ",异常信息:" + exceptionEnum.getMessage());
       }
    }
    

    至此自定义异常就结束了,现在写一个测试类感受一下

    public class MiTest{
       public static void main(String []args){
          try{
             throw new MiException(ExceptionEnum.DATABASE_EXCEPTION);
          }catch(MiException e){
             e.printException(e);
          }
       }
    }
    

    执行主函数,得到的运行结果是

    异常代码:2000,异常信息:数据库连接异常
    
    展开全文
  • java 自定义异常

    2021-03-02 15:32:51
    java 自定义异常类 以乐优商城为例 02、乐优微服务:后端返回前端数据问题 我们项目是前后端分离的项目,后端在处理过程需要给前端返回数据结果,这里分两种情况,一种是正常情况(也就是没有发生异常),另一种是...

    java 自定义异常类

    以乐优商城为例

    02、乐优微服务:后端返回前端数据问题

    我们项目是前后端分离的项目,后端在处理过程需要给前端返回数据结果,这里分两种情况,一种是正常情况(也就是没有发生异常),另一种是发生异常的情况。我们希望不管是正常情况,还是异常情况下,后端都可以给前端不同的响应状态码以及响应内容,这样有利于前端根据不同情况进行业务处理。

    1)模拟场景

    我们预设这样一个场景,假如我们模拟新增商品,只传一个id,如果id为1则抛出异常。

    2)代码

    在ly-item中编写模拟的service:

    package com.leyou.item.service;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class ItemService {
        
        public Long saveItem(Long id){
            // 模拟添加操作,如果id为1抛异常
            if(id.equals(1L)){
                throw new RuntimeException("Id不能为1!");
            }
            return id;
        }
    
    }
    

    模拟controller:

    @RestController
    public class ItemController {
        @Autowired
        private ItemService itemService;
    
        @PostMapping("/save")
        public Long saveItem(@RequestParam("id") Long id){
            return itemService.saveItem(id);
        }
    
    }
    

    3)测试

    请求
    在这里插入图片描述
    结果
    在这里插入图片描述
    经过测试,我们发现,在正常情况下只能返回200状态码,在异常情况下只能返回500状态码。显然这不满足我们的需求!接下来分两种情况进行讨论。

    03、乐优微服务:正常情况数据返回

    我们可以通过spring提供的状态码来给前端返回相应的状态码,具体操作如下:

    package com.leyou.item.controller;
    
    import com.leyou.item.service.ItemService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletResponse;
    
    @RestController
    public class ItemController {
        @Autowired
        private ItemService itemService;
    
        /**
         * ResponseEntity类
         *   1)status:修改响应状态码
         *   2)body: 修改响应正文
         * @param id
         * @return
         */
        @PostMapping("/save")
        public ResponseEntity<Long> saveItem(@RequestParam("id") Long id){
            return ResponseEntity.status(HttpStatus.CREATED).body(itemService.saveItem(id));
        }
    
    }
    

    在这里插入图片描述

    04、乐优微服务:异常情况数据返回

    1)场景说明

    依然使用上面第二步模拟的案例,参数传1,结果如下:
    在这里插入图片描述
    此刻是spring给我们封装了一个异常对象,并返回给了客户端,但是这个数据一般企业都希望自己来封装。因为这里所有异常的状态码都是500,我们希望错误的状态码更细致一些,换句话来说,就是我们希望能够自己指定异常时的状态码。而RuntimeException异常又无法自定义状态码,只有自己定义一个异常类了。

    2)自定义异常

    首先我们先在公共子模块中定义一个乐优异常类,这样每个模块都可以共用这个异常类。

    我们在ly-common模块的 com.leyou.common.exception.pojo包下创建如下异常类

    package com.leyou.common.exception.pojo;
    
    import lombok.Getter;
    
    /**
     * 自定义异常类,封装自定义异常信息
     */
    @Getter
    public class LyException extends RuntimeException{
        private Integer status;
    
        public LyException(Integer status,String message){
            super(message);
            this.status = status;
        }
    
    }
    
    
    

    3)改造ly-item-service

    我们把原来的throw new RuntimeException改为如下:

    @Service
    public class ItemService {
        
        public Long saveItem(Long id){
            // 模拟添加操作,如果id为1抛异常
            if(id.equals(1L)){
                throw new LyException(501, "Id不能为1!");
            }
            return id;
        }
    }   
    

    此刻我们就可以指定自己需要的状态码了

    问题:

    再次测试
    在这里插入图片描述
    发现状态码并没有改变。

    可以明白,spring并不认识我们的LyException,它依然把LyException当成了来RuntimeException处理了。

    所以我们要在common模块中自定义拦截异常的处理器类。

    4)全局异常拦截器

    接下来,我们使用SpringMVC提供的统一异常拦截器,因为是统一处理,我们放到ly-common项目中:

    package com.leyou.common.exception.controller;
    
    import com.leyou.common.exception.pojo.LyException;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    /**
     * 全局自定义异常拦截器(处理器)
     */
    @ControllerAdvice  // 就会覆盖SpringMVC自带异常处理
    public class LyExceptionController {
    
        /**
         * 定义异常处理定义
         */
        @ExceptionHandler(value = LyException.class) // 定义需要捕获什么异常
        public ResponseEntity<LyException> handlerException(LyException e) {
            return ResponseEntity.status(e.getStatus()).body(e);
        }
    }
    
    
    

    然后测试
    在这里插入图片描述
    但是,虽然我们要的信息都有了,但是返回的异常信息太多太多,很多都是框架的信息,前端根本用不到这些信息,如果我们将这些信息返回,那么响应的数据多了,一定程度上响应了数据的响应速度,所以我们需要进一步优化。

    5)自定义异常结果类

    为了让异常结果更友好,我们不在LyExceptionController返回LyException,而是自定义一个响应的类,这个类只包含异常响应的结果。

    提供返回异常信息的自定义类

    package com.leyou.common.exception.pojo;
    
    import lombok.Getter;
    import org.joda.time.DateTime;
    
    /**
     * 异常结果类,封装异常结果信息
     */
    @Getter
    public class ExceptionResult {
        private Integer status; //异常状态码
        private String message; //异常消息
        private String timestamp;//异常发生时间
    
        public ExceptionResult(LyException e){
            this.status = e.getStatus();
            this.message = e.getMessage();
            this.timestamp = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
        }
    
    }
    
    
    

    定义好类后,我们改造全局异常处理器类:

    package com.leyou.common.exception.controller;
    
    import com.leyou.common.exception.pojo.ExceptionResult;
    import com.leyou.common.exception.pojo.LyException;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * 全局异常拦截
     */
    @ControllerAdvice  //该注解会把所有Controller的异常拦截
    public class LyExceptionController {
    
        /**
         * 拦截具体异常方法
         */
        @ExceptionHandler(value = LyException.class)
        @ResponseBody
        public ResponseEntity<ExceptionResult> handlerException(LyException e){
            return ResponseEntity.status(e.getStatus()).body(new ExceptionResult(e));
        }
    
    
    }
    
    

    重启微服务,然后测试
    在这里插入图片描述
    到这一步,我们的全局异常问题已经解决了,要的响应码和响应内容都是我们自定义的了。

    但是还有一个问题,在实际开发中,我们的异常是很多的,而且这些异常是和前端约定好的,但现在异常响应码和异常响应内容都是写死在代码中,如果某一个响应码或者响应内容需要修改,那么所有用到这个响应码和响应内容的地方都要跟着改,很不方便,会造成很多重复的工作,所以还需要进一步优化。

    6)自定义异常枚举

    因为现在的异常响应信息包含多个内容,所以只用字符串就很难满足我们的需求,所以我们需要定义一个类来装这些信息,但是异常信息其实都是提前约定好的,所以用枚举比较符合我们需求。

    枚举:把一件事情的所有可能性列举出来。在计算机中,枚举也可以叫多例,单例是多例的一种情况 。

    单例:一个类只能有一个实例。

    多例:一个类只能有有限个数的实例。

    单例的实现:

    • 私有化构造函数
    • 在成员变量中初始化本类对象
    • 对外提供静态方法,访问这个对象

    枚举代码:

    package com.leyou.common.exception.pojo;
    
    import lombok.Getter;
    
    /**
     * 黑马程序员
     */
    @Getter
    public enum ExceptionEnum {
        INVALID_FILE_TYPE(400, "无效的文件类型!"),
        INVALID_PARAM_ERROR(400, "无效的请求参数!"),
        INVALID_PHONE_NUMBER(400, "无效的手机号码"),
        INVALID_VERIFY_CODE(400, "验证码错误!"),
        INVALID_USERNAME_PASSWORD(400, "无效的用户名和密码!"),
        INVALID_SERVER_ID_SECRET(400, "无效的服务id和密钥!"),
        INVALID_NOTIFY_PARAM(400, "回调参数有误!"),
        INVALID_NOTIFY_SIGN(400, "回调签名有误!"),
    
        CATEGORY_NOT_FOUND(404, "商品分类不存在!"),
        BRAND_NOT_FOUND(404, "品牌不存在!"),
        SPEC_NOT_FOUND(404, "规格不存在!"),
        GOODS_NOT_FOUND(404, "商品不存在!"),
        CARTS_NOT_FOUND(404, "购物车不存在!"),
        APPLICATION_NOT_FOUND(404, "应用不存在!"),
        ORDER_NOT_FOUND(404, "订单不存在!"),
        ORDER_DETAIL_NOT_FOUND(404, "订单数据不存在!"),
    
        DATA_TRANSFER_ERROR(500, "数据转换异常!"),
        INSERT_OPERATION_FAIL(500, "新增操作失败!"),
        UPDATE_OPERATION_FAIL(500, "更新操作失败!"),
        DELETE_OPERATION_FAIL(500, "删除操作失败!"),
        FILE_UPLOAD_ERROR(500, "文件上传失败!"),
        DIRECTORY_WRITER_ERROR(500, "目录写入失败!"),
        FILE_WRITER_ERROR(500, "文件写入失败!"),
        SEND_MESSAGE_ERROR(500, "短信发送失败!"),
        INVALID_ORDER_STATUS(500, "订单状态不正确!"),
        STOCK_NOT_ENOUGH_ERROR(500, "库存不足!"),
    
        UNAUTHORIZED(401, "登录失效或未登录!");
    
        private int status;
        private String message;
    
        ExceptionEnum(int status, String message) {
            this.status = status;
            this.message = message;
        }
    }
    

    改造LyException类

    package com.leyou.common.exception.pojo;
    
    import lombok.Getter;
    
    /**
     * 自定义异常类,封装自定义异常信息
     */
    @Getter
    public class LyException extends RuntimeException{
        private Integer status;
    
        public LyException(Integer status,String message){
            super(message);
            this.status = status;
        }
    
        public LyException(ExceptionEnum exceptionEnum){
            super(exceptionEnum.getMessage());
            this.status = exceptionEnum.getStatus();
        }
    }
    
    
    

    改造ly-item-service

    package com.leyou.item.service;
    
    import com.leyou.common.exception.pojo.ExceptionEnum;
    import com.leyou.common.exception.pojo.LyException;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ItemService {
        
        public Long saveItem(Long id){
            // 模拟添加操作,如果id为1抛异常
            if(id.equals(1L)){
                //throw new RuntimeException("Id不能为1!");
                throw new LyException(ExceptionEnum.UNAUTHORIZED);
            }
            return id;
        }
    
    }
    

    Memorial Day is 518 days
    I miss you
    xiaokeai

    展开全文
  • 第一次写博客,暂时在构建一个SpringBoot后台项目 前端准备采取Vue,后台采取java...第一篇 关于SpringBoot自定义异常: 第一步,创建自定义异常,源码如下: BizException: public class BizException exte...

    第一次写博客,暂时在构建一个SpringBoot后台项目 前端准备采取Vue,后台采取java 准备集成SpringBoot+shiro+mybaits基础上开展的用户的权限管理,定时任务,微信公众号等。

    第一篇 关于SpringBoot自定义异常:

       第一步,创建自定义异常,源码如下:

     

    BizException:
    public class BizException extends RuntimeException {
        private String code;  //错误码
    
        public BizException() {
        }
    
        public BizException(ErrorCode errorCode) {
            super(errorCode.getMessage());
            this.code = errorCode.getCode();
        }
    
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    }
    
     
    
     
    自定义异常编码:
    public interface ErrorCode {
        String getMessage(Object... var1);
    
        String getCode();
    }
    public enum CMMErrorCode implements ErrorCode {
        
        //用户
        USER_TITLE_IS_EXISTS("1000"),
        //错误
         EROR("9999");
    
        private static HashMap<ErrorCode, String> map = new HashMap<>();
    
        static {
    
            map.put(CMMErrorCode.USER_TITLE_IS_EXISTS, "用户标题已经存在");
    
        }
    
        private static ErrorMessage errorMessage = new ErrorMessage(map);
    
        private String code;
    
        CMMErrorCode(String code) {
            this.code = code;
        }
    
        public String getMessage(Object... args) {
            return errorMessage.getErrorMessage(this, args);
        }
    
        public String getCode() {
            return code;
        }
    }
    第二步,创建配置handler:
    @RestControllerAdvice
    public class MyExceptionHandler {
    
        @ExceptionHandler(BizException.class)
        public Map defultExcepitonHandler(HttpServletRequest request, Exception e) {
            e.printStackTrace();
            Map map = new HashMap();
            if(e instanceof BizException) {
                BizException businessException = (BizException)e;
                map.put("code", businessException.getCode());
                map.put("msg", businessException.getMessage());
            }else{
                map.put("code", -1);
                map.put("msg", "系统异常");
            }
            //未知错误
            return map;
        }
    }

    有关注解的讲解,

    @ControllerAdvice是组件注解,他使得其实现类能够被classpath扫描自动发现,如果应用是通过MVC命令空间或MVC Java编程方式配置,那么该特性默认是自动开启的。

    注解@ControllerAdvice的类可以拥有@ExceptionHandler, @InitBinder或 @ModelAttribute注解的方法,并且这些方法会被应用到控制器类层次的所有@RequestMapping方法上。

    而 @RestControllerAdvice 是@ControllerAdvice+@ResponseBody.

    第三步:运用:

    建立BizException的子类

     

    public class ResponseException extends BizException{
    
        public ResponseException(CMMErrorCode errorCode) {
            super(errorCode);
        }
    
    }
    在业务的实际运用:
    //验证用户登录名是否重复
    protected void throwIfExistAccount(String title) {
        if (existTitle(title)!=null) {
            throw new ResponseException(CMMErrorCode.USER_TITLE_IS_EXISTS);
        }
    }

    代码产生效果:

     

     

    展开全文
  • 正常业务系统中,当前后端分离时,系统即使有未知异常,也要保证接口能返回错误提示,也需要根据业务规则制定相应的异常状态码和异常提示。所以需要一个全局异常处理器。相关代码:GitHub异常下面是 Java 异常继承图...

    正常业务系统中,当前后端分离时,系统即使有未知异常,也要保证接口能返回错误提示,也需要根据业务规则制定相应的异常状态码和异常提示。所以需要一个全局异常处理器。相关代码:GitHub

    异常

    下面是 Java 异常继承图:

    ┌───────────┐

    │ Object │

    └───────────┘

    ┌───────────┐

    │ Throwable │

    └───────────┘

    ┌─────────┴─────────┐

    │ │

    ┌───────────┐ ┌───────────┐

    │ Error │ │ Exception │

    └───────────┘ └───────────┘

    ▲ ▲

    ┌───────┘ ┌────┴──────────┐

    │ │ │

    ┌─────────────────┐ ┌─────────────────┐┌───────────┐

    │OutOfMemoryError │... │RuntimeException ││IOException│...

    └─────────────────┘ └─────────────────┘└───────────┘

    ┌───────────┴─────────────┐

    │ │

    ┌─────────────────────┐ ┌─────────────────────────┐

    │NullPointerException │ │IllegalArgumentException │...

    └─────────────────────┘ └─────────────────────────┘

    根据编译时是否需要捕获,异常可以分为两类:1、写代码时,编译器规定必须捕获的异常,不捕获将报错;2、(抛出后)不必须捕获的异常,编译器对此类异常不做处理。

    必须捕获的异常:Exception 以及 Exception 除去 RuntimeException 的子类。

    不必须捕获的异常:Error 以及 Error 的子类;RuntimeException 以及 RuntimeException 的子类。

    必须捕获的异常:

    @GetMapping("/testThrowIOException")

    public ApiResponse testThrowIOException() {

    testThrowIOException(); // 将报错

    return ApiResponse.success();

    }

    private void throwIOException() throws IOException {

    System.out.println("testThrowIOException");

    throw new IOException();

    }

    不必须捕获的异常:

    @GetMapping("/testThrowRuntimeException")

    public ApiResponse testThrowRuntimeException() {

    throwRuntimeException(); // 不报错

    return ApiResponse.success();

    }

    private void throwRuntimeException() { // 无需 throws

    System.out.println("testThrowRuntimeException");

    throw new ArrayIndexOutOfBoundsException();

    }

    不过在运行时,任何异常都可以进行捕获处理,避免接口没有返回值的情况。

    抛异常

    常见异常处理方式有两种,1、捕获后处理,2、抛出。抛出也分为捕获后抛出和直接抛出。

    当本身没有异常,却使用 throws 抛出异常时,此时相当于没有抛异常(将拦截不到异常)。

    @GetMapping("/testThrowIOException2")

    public ApiResponse testThrowIOException2() throws IOException {

    throwIOException2();

    return ApiResponse.success();

    }

    private void throwIOException2() throws IOException {

    System.out.println("testThrowIOException");

    }

    打印异常

    打印异常可以使用 Logback 打印,其相关方法的使用: log.error(e.getMessage(), e); 相当于下面这两条语句:

    System.out.println(e.getMessage()); // 打印异常信息

    e.printStackTrace(); // 打印异常调用栈

    减少 NullPointException 的方式是设置默认值。

    测试 Error

    测试 StackOverflowError,设置栈的大小为 256K,IDEA(VM options): -Xss256k;命令行:java -Xss256k JavaVMStackSOF

    class JavaVMStackSOF {

    public int stackLength = 1;

    public void stackLeak() {

    stackLength++;

    stackLeak();

    }

    public static void main(String[] args) throws Throwable {

    JavaVMStackSOF oom = new JavaVMStackSOF();

    try {

    oom.stackLeak();

    } catch (Throwable e) {

    System.out.println("stack length:" + oom.stackLength);

    throw e;

    }

    }

    }

    stack length:1693

    Exception in thread "main" java.lang.StackOverflowError

    at wang.depp.exception.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:10)

    at wang.depp.exception.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:11)

    ...

    测试 OutOfMemoryError,设置 Java 堆的大小为 128M,IDEA(VM options):-Xms10M -Xmx10M;命令行:java -Xms10M -Xmx10M wang.depp.exception.HeapOOM(如果类中包含 package 路径,需 cd 到 java 目录后运行此命令)

    package wang.depp.exception;

    import java.util.ArrayList;

    import java.util.List;

    public class HeapOOM {

    static class OOMObject {

    }

    public static void main(String[] args) {

    List list = new ArrayList<>();

    while (true) {

    list.add(new OOMObject());

    }

    }

    }

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    at java.base/java.util.Arrays.copyOf(Arrays.java:3720)

    at java.base/java.util.Arrays.copyOf(Arrays.java:3689)

    ...

    全局异常处理器

    自定义异常

    自定义异常从 RuntimeException 派生,构造方法使用 super(message); 和 super(message, cause);。添加状态码和参数属性。

    public abstract class BaseException extends RuntimeException {

    private int code; // 状态码

    private String message;

    private Object[] args; // 参数

    private IResponseEnum responseEnum;

    public BaseException(IResponseEnum iResponseEnum, Object[] args, String message) {

    super(message);

    this.code = iResponseEnum.getCode();

    this.message = message;

    this.responseEnum = iResponseEnum;

    this.args = args;

    }

    public BaseException(IResponseEnum iResponseEnum, Object[] args, String message, Throwable cause) {

    super(message, cause);

    this.code = iResponseEnum.getCode();

    this.message = message;

    this.responseEnum = iResponseEnum;

    this.args = args;

    }

    public int getCode() {

    return this.code;

    }

    public String getMessage() {

    return this.message;

    }

    public Object[] getArgs() {

    return this.args;

    }

    public IResponseEnum getResponseEnum() {

    return this.responseEnum;

    }

    }

    当前服务的业务异常不用每个单独作为一个异常类,可通过 message 和 code 来做一个区分。

    public class LoanException extends BusinessException {

    public static LoanException INTERNAL_ERROR = new LoanException(ResponseEnum.SERVER_ERROR);

    public static LoanException REJECT = new LoanException(ResponseEnum.REJECT);

    public static LoanException BAND_FAIL = new LoanException(ResponseEnum.BAND_FAIL);

    public static LoanException FORBIDDEN = new LoanException(ResponseEnum.FORBIDDEN);

    public static LoanException DB_OPTIMISTIC_LOCK = new LoanException(ResponseEnum.DB_OPTIMISTIC_LOCK);

    public LoanException(IResponseEnum responseEnum) {

    super(responseEnum, null, responseEnum.getMessage());

    }

    public LoanException(IResponseEnum responseEnum, String message) {

    super(responseEnum, null, message);

    }

    }

    @GetMapping("/testLoanException")

    private ApiResponse testLoanException() {

    throw LoanException.REJECT;

    }

    为不同的业务错误场景设置相关枚举类型(状态码、错误提示)。为枚举添加可断言判断抛出异常功能。

    public interface Assert {

    BaseException newException(Object... var1);

    BaseException newException(Throwable var1, Object... var2);

    default void assertNotNull(Object obj) {

    if (obj == null) {

    throw this.newException((Object[])null);

    }

    }

    default void assertNotNull(Object obj, Object... args) {

    if (obj == null) {

    throw this.newException(args);

    }

    }

    default void assertTrue(boolean flag) {

    if (!flag) {

    throw this.newException((Object[])null);

    }

    }

    default void assertTrue(boolean flag, Object... args) {

    if (!flag) {

    throw this.newException((Object[])null);

    }

    }

    }

    public interface BusinessExceptionAssert extends IResponseEnum, Assert {

    default BaseException newException(Object... args) {

    String msg = MessageFormat.format(this.getMessage(), args);

    return new BusinessException(this, args, msg);

    }

    default BaseException newException(Throwable t, Object... args) {

    String msg = MessageFormat.format(this.getMessage(), args);

    return new BusinessException(this, args, msg, t);

    }

    }

    @Getter

    @AllArgsConstructor

    public enum ResponseEnum implements BusinessExceptionAssert {

    SUCCESS(111000,"success"),

    PARAM_VALID_ERROR(111001,"param check error."),

    SERVER_ERROR(111002,"server error."),

    LOGIN_ERROR(111003,"login error"),

    UNAUTHORIZED(111004, "unauthorized"),

    SERVICE_ERROR(111005,"service error."),

    FORBIDDEN(114003, "forbidden"),

    TIMEOUT(114000, "timeout"),

    REJECT(114001, "reject"),

    EMAIL_CONFLICT(114002, "email conflict"),

    EMAIL_VERIFY_FAIL(114004, "email verify fail"),

    DB_OPTIMISTIC_LOCK(114008, "update fail"),// 数据库乐观锁

    EMAIL_SEND_FAIL(114011, "email send fail"),

    DATA_NOT_FOUND(114012, "data not found"),

    LOGIN_TOKEN_VERIFY_FAIL(114014, "login token verify fail"),

    ;

    /**

    * 返回码

    */

    private int code;

    /**

    * 返回消息

    */

    private String message;

    }

    @GetMapping("/test")

    public ApiResponse test(String value) {

    ResponseEnum.SERVICE_ERROR.assertNotNull(value);

    return ApiResponse.success("true");

    }

    全局异常管理器

    @Slf4j

    @ControllerAdvice

    public class GlobalExceptionHandler {

    /**

    * 生产环境

    */

    private final static String ENV_PROD = "production";

    /**

    * 当前环境

    */

    @Value("${env}")

    private String profile;

    /**

    * 业务异常

    *

    * @param e 异常

    * @return 异常结果

    */

    @ExceptionHandler(value = BusinessException.class)

    @ResponseBody

    public ApiResponse handleBusinessException(BaseException e) {

    log.error(e.getMessage(), e);

    log.error("BusinessException");

    return ApiResponse.fail(e.getCode(), e.getMessage());

    }

    /**

    * 非错误编码类系统异常

    *

    * @param e 异常

    * @return 异常结果

    */

    @ExceptionHandler(value = SystemException.class)

    @ResponseBody

    public ApiResponse handleBaseException(SystemException e) {

    return getServerErrorApiResponse(e);

    }

    /**

    * Controller 上一层相关异常

    *

    * @param e 异常

    * @return 异常结果

    */

    @ExceptionHandler({NoHandlerFoundException.class,

    HttpRequestMethodNotSupportedException.class,

    HttpMediaTypeNotSupportedException.class,

    MissingPathVariableException.class,

    MissingServletRequestParameterException.class,

    TypeMismatchException.class,

    HttpMessageNotReadableException.class,

    HttpMessageNotWritableException.class,

    // BindException.class,

    // MethodArgumentNotValidException.class

    HttpMediaTypeNotAcceptableException.class,

    ServletRequestBindingException.class,

    ConversionNotSupportedException.class,

    MissingServletRequestPartException.class,

    AsyncRequestTimeoutException.class

    })

    @ResponseBody

    public ApiResponse handleServletException(Exception e) {

    return getServerErrorApiResponse(e);

    }

    /**

    * 未定义异常。相当于全局异常捕获处理器。

    *

    * @param e 异常

    * @return 异常结果

    */

    @ExceptionHandler(value = Exception.class)

    @ResponseBody

    public ApiResponse handleException(Exception e) {

    return getServerErrorApiResponse(e);

    }

    private ApiResponse getServerErrorApiResponse(Exception e) {

    int code = ResponseEnum.SERVER_ERROR.getCode();

    String productShowMessage = ResponseEnum.SERVER_ERROR.getMessage();

    if (ENV_PROD.equals(profile)) {

    return ApiResponse.fail(code, productShowMessage);

    }

    return ApiResponse.fail(code, e.getMessage());

    }

    }

    使用 @ControllerAdvice + @ExceptionHandler 实现对指定异常的捕获。此时运行时异常和 Error 也能被捕获。

    延伸阅读

    展开全文
  • 这里 如果 返回的是null 代码正常可运行,但是页面的控制台的status 却是500,如果返回的是 new 一个 ModelAndView 的话,页面正常 ,状态码为200 ,但是其中是什么逻辑 ,我不清楚,为什么返回null的时候 页面...
  • 2、创建Exception类(自定义异常类) 并继承RuntimeException public class Exception extends RuntimeException { /** * 状态码 */ private Integer code; /** * 错误信息 */ private String msg; /*...
  • SpringBoot中自定义异常处理 在SpringBoot中自定义error页面有两种,一种是静态页面,一种是动态页面. 1.静态异常页面 使用HTTP响应来命名页面,如404.html、405.html 直接定义4xx.html,表示400-499的状态都显示改...
  • 自定义异常

    2020-08-21 00:15:41
    @Data @AllArgsConstructor ... /**异常状态码*/ private Integer code; /**异常信息*/ private String msg; } # 统一异常类 ```java @ControllerAdvice public class exceptionHandler { @Ex
  • 自定义RestTemplate的...如若是这两类状态码,会执行handleError()抛出异常 并不想让它抛异常 在一些业务场景下,或许我们并不想让它抛异常(即便我们可以捕获异常,额外做处理),那么就需要我们ResponseErrorHandle
  • 一、异常现象在 JAVA 开发中我们经常会使用RestTemplate进行远程接口调用,如果请求的接口出现异常:超时、服务不存在等等情况,这时响应状态不是200,而是400、500等等状态码,这种情况下,程序便会抛出异常,如下...
  • 本周在看陈杰写的自定义异常的微信异常时,使用的是自定义异常状态码和信息,在出错时将他抛出,并用@ExceptionHandler注解定义一个全局异常处理器,根据异常的内容向前台发送状态码和信息,处理异常的代码如下图://...
  • java全局异常处理

    2018-12-08 14:28:42
    在javaEE开发过程中,异常处理是必不可少的,为了不直接给前端500系统错误的状态码,一般对于可预知的异常,我们会自定义异常,但是对于不可预知的异常,我们要怎么处理呢?下面 我们就此问题聊聊。 定义全局异常...
  • 分析一下处理逻辑流程,首先 捕获异常 , 获取异常信息, 记录异常信息, 返回异常状态码以及自定义给前台的异常信息。 抽出其中的共性问题 记录异常是必须的共用的 返回的异常状态码以及异常信息自定义根据不同的...
  • 使用MR求每个浏览器的数量,过滤掉状态码大于400的数据,或者状态码为空的数据,要求用对象封装数据,输出浏览器和数量 数据说明: data[0] 用户ip,0 data[1] 客户端用户名 data[3]请求时间 data[5] ...
  • //状态码 private Integer code; //提示信息 private String msg; //数据 private Object data; public AjaxResult() { } //自定义返回结果的构造方法 public AjaxResult(Boolean succe.
  • Sentinel默认返回 Blocked by Sentinel (flow limiting),状态码419 sentinel官网地址下载源码 如果github下载不下来可以到我上传的资源上下载 源码中 Sentinel-master\sentinel-adapter\sentinel-spring-webmvc-...
  • 统一结果返回目前的前后端开发大部分...响应状态码状态码描述;响应数据其他标识符结果类枚举前三者可定义结果枚举,如:success,code,message@Getter public enum ResultCodeEnum { SUCCESS(true,20000,"成功...
  • 异常可作为正常的错误状态使用,如"在业务层中,判断到用户不存在,可以直接抛出异常信息,在Web层接口中进行捕获,并返回错误",这是正确的错误信息返回。这样做的益处是函数中不需要一层一层返回对应的错误原因...
  • 20大进阶架构专题每日送达作者:永动的图灵机juejin.im/post/5e073980f265da33f8653f2e统一结果返回...响应状态码状态码描述;响应数据其他标识符结果类枚举前三者可定义结果枚举,如:success,code,message@G...
  • Servlet自定义错误页面

    2020-08-11 19:32:26
    500 Server Inner Error 服务器内部错误,一般都是服务器Java程序出现异常 404和500是HTTP协议状态码,是W3C制定的 正常响应的HTTP协议状态码是200 可以在web.xml中添加错误页面 <error-page> <error-...
  • 在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示。SpringBoot在页面 ...我们会发现无论是发生什么错误,SpringBoot都会返回一个状态码以及一个错误页面...
  • 1.1自定义返回状态码的方式1.1.1 用ResponseEntity1.1.2@ResponseStatus定义在异常类1.1.3@ResponseStatus定义在方法上1.1.4@RestControllerAdvice2 1返回的状态吗不对? 1.1自定义返回状态码的方式 1.1.1 用...
  • initial_frame 代码地址:Github项目地址 包含功能 接收参数验证 统一异常处理 ...统一异常处理(就是做个切面,然后把状态码,状态信息放入同一返回类型里) 进行测试 log4j引入-相关配置网上找下

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 135
精华内容 54
关键字:

java自定义异常状态码

java 订阅