• 挑战常规--不要这样使用异常


    不要这样使用异常

    在一些使用spring框架的项目中,经常可以看到这样的代码:
    在业务代码中抛出自定义异常,在全局异常控制中自定义输出

    @RestController
    @RequestMapping("/api/TestServer")
    public class TestServer
    {
    	@PostGet("getUser")
    	public User getUser(String userName)
    	{
    		//....
    		
    		throw new UserNotFoundException();
    	}
    	//....
    }
    
    public class UserNotFoundException extends RuntimeException
    {
    	public UserNotFoundException(){
    		super("用户不存在");
    	}
    }
    
    @RestControllerAdvice
    public class MyExceptionHandler
    {
    	@ExceptionHandler
    	Map handleUserNotFoundException(UserNotFoundException ex)
    	{
    		Map result=new HashMap();
    		result.put("code",100);
    		result.put("message","用户不存在");
    		return result;
    	}
    	//...
    }
    

    为什么说这不是一个好的做法呢?先看看正确的做法应该是:
    定义全局输出封装类,正常或异常业务输出都由这个类封装

    public class Message<T> 
    {
    	/**
    	 * 响应代码,0为正常
    	 */
        private int code;
        /**
         * 用于描述code对应信息
         */
        private String msg;
    	//.....
    }
    

    定义一个基础常规异常表

    public enum CodeEnu implements CodeInter 
    {
    	/**正常返回*/OK, 
    	/**未知异常时,最后返回*/OTHER("其他异常"), 
    	NOTEMPTY("参数不能为空"), FORMATERROR("参数格式不正确"), 
    //....
    }
    

    替换抛出异常的业务代码

    @RestController
    @RequestMapping("/api/TestServer")
    public class TestServer
    {
    	@PostGet("getUser")
    	public Message<User> getUser(String userName)
    	{
    		//....
    		
    		return Message.error(CodeEnu.USER_NOTFOUND_ERROR);
    	}
    	//....
    }
    
    @RestControllerAdvice
    public class MyExceptionHandler
    {
    	@ExceptionHandler
    	Message<Void> handleException(Exception ex)
    	{
    		return Message.error(CodeEnu.OTHER); 
    	}
    }
    

    抛出异常 vs 返回结果

    有时候我们选择抛出异常,有时候选择返回结果。这要这两个者的优缺点说起:

    1. 异常能够详细的跟踪错误出处
    2. 抛出异常也意味着降低些性能

    在业务中,抛出异常不好的点有:1.不需要详细的跟踪错误,最终也只是输出简要信息。2.是可预知的业务结果,而不是出现运行问题。3.重复的处理转发,由结果转异常抛出,再将异常抛出转结果输出,转了一圈又回来的浪费性能处理。

    思考

    1. 在jdk8中,提供java.util.Optional 类也是用来减少抛出NullPointerException
    2. 经常需要用到将InputStream 读取出来的工具方法,如读取网络、文件,那么这个方法该抛出IOException还是返回null?
  • 相关阅读:
    Hbase-06-Snapshot原理
    Hbase-05-备份表数据
    Hbase-04-hbck
    Python Exception Handling
    10.TiPD 调度
    8.存储引擎TiFlash
    6.TiDB数据库的存储
    7.存储引擎TiKV
    4.Tidb SQL优化(一)
    5.TiDB SQL优化(二)
  • 原文地址:https://www.cnblogs.com/loveheihei/p/11315036.html
Copyright © 2020-2023  润新知