项目中统一处理抛出异常,不影响用户体验

 

先整体说一下思路:

当程序中:我们抛出自定异常,如

    throw new BaseException(10002006);

那么BaseException类中利用方法,

    public BaseException(int code) {
        this(code, ResBundle.getMessage(String.valueOf(code)));

    }

将配置文件中的错误信息存到改异常中,然后由继承HandlerExceptionResolver的ExceptionResolver拦截,向用户展示友好界面。

备注:之后又接触了一个更加简单处理Controller层异常的方法,利用@ControllerAdvice与@ExceptionHandler注解处理。

@ControllerAdvice
public class MyExceptionHandler {
	
	@ResponseBody
	@ExceptionHandler(value=Exception.class)
	public Map errorHandler(Exception ex){
		Map map=new HashMap();
		map.put("code", -1);
		map.put("msg", ex.getMessage());
		return map;
	}
}

 

 

 

 

新建异常处理类,要继承HandlerExceptionResolver。

@Component
public class ExceptionResolver implements HandlerExceptionResolver {
    private final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class);

    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception e) {
        String errorMessage = null;
        if (e instanceof BaseException) {
            errorMessage = e.getMessage();
        } else if (e instanceof UnauthorizedException) {
            errorMessage = "没有权限";
        } else if (e instanceof MaxUploadSizeExceededException) {
            errorMessage = "文件太大啦!
请选择更小一些的文件重试!"; } else if (e instanceof RuntimeException && e.getCause() instanceof BaseException) { errorMessage = e.getCause().getMessage(); } else { logger.error(e.getMessage(), e); errorMessage = "未知错误,请联系管理员!"; } Map result = new HashMap(); result.put("status", false); result.put("msg", (Strings.isBlank(errorMessage) ? "未知错误,请联系管理员!" : errorMessage)); if (HttpUtils.isAjaxRequest(request)) { return new ModelAndView(new FastJsonJsonView(), result); } if (handler instanceof HandlerMethod) { if (HttpUtils.isJsonResponse(request, (HandlerMethod) handler)) { return new ModelAndView(new FastJsonJsonView(), result); } } // 页面指定状态为500,便于上层的resion或者nginx的500页面跳转,由于error/error不适合对用户展示 // response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return new ModelAndView("error/500", result); } }

其中的BaseException类是项目中所以自定义异常都要继承的。

/**
 * 
 * 异常基类,所有异常都必须继承于此异常 . 
*/ public class BaseException extends RuntimeException { private static final long serialVersionUID = -5875371379845226068L; /** * 具体异常码 */ protected int code; protected BaseException() { super(); } public int getCode() { return code; } /** * 实例化异常 * * @param msgFormat * @param args * @return */ protected BaseException newInstance(String msgFormat, Object... args) { return new BaseException(this.code, msgFormat, args); } public BaseException(int code) { this(code, ResBundle.getMessage(String.valueOf(code))); } public BaseException(int code, Object... args) { this(code, ResBundle.getMessage(String.valueOf(code)), args); } protected BaseException(int code, String msgFormat, Object... args) { super(String.format(msgFormat, args)); this.code = code; } protected BaseException(String message, Throwable cause) { super(message, cause); } public BaseException(Throwable cause) { super(cause); } protected BaseException(String message) { super(message); } }

 

当我们抛出自定义异常时,我们利用自定义的ResBundle(其中封装了ResourceBundle的一些信息),

ResourceBundle是去读取配置文件的。

public class ResBundle {
    private static Log log = LogFactory.getLog(ResBundle.class);

    private static Map resMap = new HashMap();

    private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
        public Enumeration getKeys() {
            return null;
        }

        protected Object handleGetObject(String key) {
            return null;
        }

        public String toString() {
            return "NULL_BUNDLE";
        }
    };

    private static ResourceBundle getBundle(String resourceName) {
        ResourceBundle rb = resMap.get(resourceName);
        if (rb == null) {
            try {
                rb = ResourceBundle.getBundle(resourceName, Locale.getDefault());
                if (rb == null) {
                    rb = NULL_BUNDLE;
                }
                resMap.put(resourceName, rb);
            } catch (Throwable mre) {
                log.error("No resource property file in the classpath or in the res folder.", mre);
            }
        }
        return rb;
    }

    public static String getString(String key) {
        return getResString("resource", key, null);
    }

    public static String getMessage(String key) {
        return getResString("resource", key, null);
    }

    public static String getString(String key, String defaultValue) {
        return getResString("resource", key, defaultValue);
    }

    public static String getMessage(String key, String defaultValue) {
        return getResString("resource", key, defaultValue);
    }

    public static String getResString(String resourceName, String key) {
        return getResString(resourceName, key, null);
    }

    public static String getResString(String resourceName, String key, String defaultValue) {
        String value = getBundle(resourceName).getString(key).trim();
        return Strings.isBlank(value) ? defaultValue : value;
    }

}

项目中统一处理抛出异常,不影响用户体验_第1张图片

配置错误信息如图。

 

 

 

 

你可能感兴趣的:(java,#,异常处理)