SpringBoot- optimization project in exception handling

1.0 Why do we need an exception

About Java exception, you can refer to before I wrote a blog Java Basics (8) - the use of system abnormalities and projects , some of which referred to an abnormal thinking and how to use exceptions.

Why do we need it abnormal?

I think we can think about from three different angles.

  1. Back-end developers: make the back-end developers to quickly locate where the problem by logging into the program, and to resolve problems.
  2. Front-end developer: Depending on the type of exception, do the appropriate style show
  3. User: er er? ? Users do not understand technology, you do not need to know what type of exception is just text or graphical prompts.

For example, CSDN upload files prompt a network error, my side of the network will have no problem, but is busy or internal server error, so we throw to the wrong network identity.
Here Insert Picture Description

1.1 1.0 Exception Handling

Therefore, abnormal throughout between the rear and front-end, back-end throws an exception, the front needs to show different pages presented to the user based on an exception, this is the most basic way of handling exception:

Here Insert Picture Description

1.2 Exception Handling 2.0

In 1.0 mode, essentially by abnormal distal end of the capture and conversion, but since generated by the backend abnormal, then the most correct approach is to be handled by the rear end, which is drawn out some of the ways the exception handling . The current method is to use simple implementation status code instead of the exception:

The exception to the rear end of the captured and processed into an abnormal status code, corresponding to the front end processing according to display status code:

Here Insert Picture Description

The advantage of this is:

1. Make a back-end exception handling, specific information will not be made to expose anomalies, safer
2. The front end can only be based on the back-end of the corresponding page jump appointment to state code, without the need for additional exceptions process, only properly handle each end of each side logic can achieve the goal of high cohesion, low coupling.

1.3 Exception Handling a first embodiment

The first way is very simple and crude, where only possible anomalies in the service layer throw an exception, then captured and processed in the controller layer, which is unusual for a small number of cases:

Below in conjunction with a template message module to touch on how to use exception handling, which is a project SpringBoot / SSM, the thinking process is an exception thrown in the service layer, and the layer to be unified in the controller abnormal capture and processing:

  • ArgsLoseException
/**
 * @Auther: ARong
 * @Description: 参数缺失异常
 **/
public class ArgsLoseException extends Exception {
    public ArgsLoseException(){}
    public ArgsLoseException(String message){super(message);}
}
  • ArgsErrorException
/**
 * @Auther: ARong
 * @Description: 参数错误异常
 **/
public class ArgsErrorException extends Exception {
    public ArgsErrorException() {}
    public ArgsErrorException(String messasge) {super(messasge);}
}
  • TemplateMessageSerivceImp
/**
 * @Auther: ARong
 * @Description: 发送模板消息
 **/
@Service
@Transactional
@Slf4j
public class TemplateMessageSerivceImp implements TemplateMessageSerivce {
    @Autowired
    private MessageUtil messageUtil;
/**
     * @param messageEntity
     * @param opeType
     * @auther: Arong
     * @description: 注册成功后发送
     * @param: [messageEntity]
     * @return: AjaxResult
     */
    @Override
    public AjaxResult sendMessage(MessageEntity messageEntity, String opeType) throws ArgsLoseException, ArgsErrorException { 
        Map map = MessageUtil.MessageMap(
                messageEntity.getOpenId(),
                messageEntity.getPage(),
                messageEntity.getFormId()
        );

        if (opeType == null || "".equals(opeType.trim())) {
            throw new ArgsLoseException("opeType参数缺失");
        }

        if (!"YES".equals(opeType)) {
            throw new ArgsErrorException("opeType参数错误");
        }

        //...业务逻辑
        return null;
    }
  }

At this point we focused on, controller layer should be how to handle these exceptions do?

First, we need to note that an exception should not be allowed to be directly exposed to the eyes of the user, but rather to an abnormal state into a kind of front-end code, so that the front end to do the appropriate treatment, for example, to prompt the user which operates according to status code is wrong , or that the network delays, etc., in short focus status code conventions and front and rear ends into a condition abnormality in the eyes of the user:

  • TemplateMessageController
@Controller
@CrossOrigin
@RequestMapping(value = "/message")
@ResponseBody
@Slf4j
public class TemplateMessageController {
    @Autowired
    private TemplateMessageSerivce templateMessageSerivce;

    /**
     * @auther: Arong
     * @description: 注册成功后发送
     * @param: [messageEntity]
     * @return: AjaxResult
     */
    @PostMapping(value = "/sendMessage")
    public AjaxResult sendMessage(
            @ModelAttribute MessageEntity messageEntity,
            @RequestParam(name = "opeType") String opeType //操作类型
    ) {
        AjaxResult ajaxResult = null;
        try {
            ajaxResult = templateMessageSerivce.sendMessage(messageEntity, opeType);
        } catch (Exception e) {
            //打印异常栈堆路径
            e.printStackTrace();
            //分不同异常给前端返回不同的状态码(不要将异常暴露给前端,而是通过状态码让前端去反应)
            if (e instanceof ArgsLoseException) {
            	//回传状态码501
                return new AjaxResult(501, "传入opeType为空");
            } else if (e instanceof ArgsErrorException) {
            	//回传状态码502
                return new AjaxResult(502, "参数错误");
            }
        }
        return ajaxResult;
    }}

This exception handling in a custom way to deal with very few exceptions when has been good enough, but as more and more custom exception, then you need to deal with the more abnormal the controller as follows:


			if (e instanceof ArgsLoseException) {
            	//回传状态码501
                return new AjaxResult(501, "传入opeType为空");
            } else if (e instanceof ArgsErrorException) {
            	//回传状态码502
                return new AjaxResult(502, "参数错误");
            } else if (e instanceof Xx1Exception) {
            	//...
			} else if (e instanceof Xx2Exception) {
            	//...
			} else if (e instanceof Xx3Exception) {
            	//...
			}

So, the next need to optimize the way exception handling

1.4 Exception Handling The second way - global exception handler

In order to optimize the above-described exception handling problems else if excessive, and incorporated herein SpringBoot global exception handling, exception handling code is simplified, the following is a Demo program, not related to specific service module, it is only exemplary:

  • AjaxResult return results
/**
 * @Auther: ARong
 * @Description: 处理结果
 */
@Data
public class AjaxResult {
    public AjaxResult() {
    }

    public AjaxResult(int code, String message) {
        this.code = code;
        this.message = message;
    }

    private int code;
    private String message;
}
  • GlobalException global exception, the inside inner class define a custom exception
/**
 * @Auther: ARong
 * @Description: 全局异常定义
 */
public class GlobalException {
    /*
     * @Author ARong
     * @Description 参数缺少异常
     **/
    @Data
    public static class ArgsLoseException extends RuntimeException{
        private int code = 501;
        private String message;

        public ArgsLoseException(String message) {
            this.message = message;
        }
    }

    /*
     * @Author ARong
     * @Description 参数错误异常
     **/
    @Data
    public static class ArgsErrorException extends RuntimeException{
        private int code = 502;
        private String message;

        public ArgsErrorException(String message) {
            this.message = message;
        }
    }
}
  • GlobalExceptionHandler
    use @ControllerAdvice and @ExceptionHandler achieve global exception handler
/**
 * @Auther: ARong
 * @Description: 全局异常处理器
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /*
     * @Author ARong
     * @Description 捕捉异常并进行处理
     * @Param
     * @return
     **/
    @ExceptionHandler(value = Exception.class)
    public AjaxResult exceptionHandler(Exception e) {
        // 打印异常调用栈
        e.printStackTrace();
        AjaxResult result = new AjaxResult();

        int code = 500;
        String message = "服务器出现错误";

        // 如果是自定义异常则进行转化
        if (e instanceof GlobalException.ArgsErrorException) {
            // 参数错误异常
             code = ((GlobalException.ArgsErrorException) e).getCode();
             message = ((GlobalException.ArgsErrorException) e).getMessage();
        }
        if (e instanceof GlobalException.ArgsLoseException) {
            // 参数缺失异常
            code = ((GlobalException.ArgsLoseException) e).getCode();
            message = ((GlobalException.ArgsLoseException) e).getMessage();
        }

        result.setCode(code);
        result.setMessage(message);
        return result;
    }
}
  • DemoController control layer
/**
 * @Auther: ARong
 * @Description: 控制层
 */
@Controller
@ResponseBody
public class DemoController {
    @Autowired
    private DemoService demoService;

    @RequestMapping(value = "/get")
    public AjaxResult get(
            @RequestParam(name = "id") String id
    ) {
        AjaxResult result = demoService.get(id);
        return result;
    }
}
  • DemoService business layer
/**
 * @Auther: ARong
 * @Description: 业务层
 */
@Service
public class DemoService {
    public AjaxResult get(String id) {
        if ("bug".equals(id)) {
            // 参数错误
            throw new GlobalException.ArgsErrorException("参数错误");
        }
        if ("null".equals(id)) {
            // 参数缺失
            throw new GlobalException.ArgsLoseException("参数缺失");
        }
        return new AjaxResult(200, "OK");
    }
}

After configuring a global exception handler, a Controller layer on a need to capture and process the custom exception, and the processor to do all the processing corresponding to, and return a status code. Start the project, using postMan simple test:

  1. normal circumstances

Here Insert Picture Description

  1. Trigger parameter error exception
    Here Insert Picture Description

  2. Trigger abnormal parameters are missing
    Here Insert Picture Description

After the above steps, you can achieve a basic global exception handler, which will be greatly simplified and less redundant code amount controller layer, to improve the readability of the program, the rest of the more important thing is how the agreement should state code how do the front-end and jump.

Thanks

https://blog.csdn.net/Colton_Null/article/details/84592748

Published 309 original articles · won praise 205 · Views 300,000 +

Guess you like

Origin blog.csdn.net/pbrlovejava/article/details/104077976