赞
踩
在 Java EE 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都难以避免遇到各种异常需要处理的问题。若不对异常进行处理的话,给用户看到异常信息是不好的,对不懂程序的用户来说还以为你的网站出问题了;对懂程序的人来说,看到你的异常信息,会显得很 low,特别是 SQL 出错,甚至还会暴露你的数据库字段。
在开发中还可以根据自己业务的异常情况来自定义业务逻辑异常类,一般继承于 java.lang.RuntimeException。
比如虽然登录出错,也响应 JSON 数据,但其需要提示的消息更详细,所以通过自定义异常,再利用 Spring MVC 全局处理异常方式,针对这个异常进行专门处理。
package com.itzhouwei.exception; /**** * 自定义异常类 */ public class BusinessException extends RuntimeException{ private BusinessExceptionCode code; public BusinessException (BusinessExceptionCode code) { super(code.getDesc()); this.code = code; } public BusinessExceptionCode getCode() { return code; } public void setCode(BusinessExceptionCode code) { this.code = code; } /** * 不写入堆栈信息,提高性能 */ @Override public Throwable fillInStackTrace() { return this; } }
package com.itzhouwei.exception; public enum BusinessExceptionCode { USER_LOGIN_NAME_EXIST("用户名已存在"), LOGIN_USER_ERROR("用户名不存在或密码错误"), NOT_PERMISSION("没有权限") ; private String desc; BusinessExceptionCode(String desc) { this.desc = desc; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
package com.itzhouwei.web.advice; import com.alibaba.fastjson.JSON; import com.itzhouwei.exception.BusinessException; import com.itzhouwei.qo.JsonResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ui.Model; import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.HandlerMethod; import javax.servlet.http.HttpServletResponse; /** * 统一异常处理、数据预处理等 */ @ControllerAdvice public class ControllerExceptionHandler { private static final Logger LOG = LoggerFactory.getLogger(ControllerExceptionHandler.class); /** * 校验异常统一处理 * @param e * @return */ @ExceptionHandler(value = BindException.class) @ResponseBody public JsonResult validExceptionHandler(BindException e) { JsonResult commonResp = new JsonResult(); LOG.warn("参数校验失败:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage()); commonResp.setSuccess(false); commonResp.setMsg(e.getBindingResult().getAllErrors().get(0).getDefaultMessage()); return commonResp; } // @ExceptionHandler(value = BusinessException.class) // @ResponseBody // public JsonResult validExceptionHandler(BusinessException e) { // JsonResult commonResp = new JsonResult(); // LOG.warn("业务异常:{}", e.getCode().getDesc()); // commonResp.setSuccess(false); // commonResp.setMsg(e.getCode().getDesc()); // return commonResp; // } /** * 校验异常统一处理 * @param e * @return * * 这里不需要自己去拼接json 所以我导入Fastjson jar包 进行处理 */ @ExceptionHandler(BusinessException.class) public String exceptionHandler(BusinessException e, HandlerMethod method, Model model, HttpServletResponse response) throws Exception{ e.printStackTrace(); // 方便开发的时候找 bug // 若原本控制器的方法是返回 JSON,现在出异常也应该返回 JSON // 获取当前出现异常的方法,判断是否有 ResponseBody 注解,有就代表需要返回 JSON LOG.warn("业务异常:{}", e.getCode().getDesc()); if(method.hasMethodAnnotation(ResponseBody.class)){ response.setContentType("application/json;charset=UTF-8"); response.getWriter() .print(JSON.toJSONString(new JsonResult(false,e.getCode().getDesc() ))); return null; } model.addAttribute("errorMsg", e.getCode().getDesc()); // 若原本控制器的方法是返回 HTML,现在也应该返回 HTML return "common/error"; } /** * 校验异常统一处理 * @param e * @return */ @ExceptionHandler(value = Exception.class) @ResponseBody public JsonResult validExceptionHandler(Exception e) { JsonResult commonResp = new JsonResult(); LOG.error("系统异常:", e); commonResp.setSuccess(false); commonResp.setMsg("系统出现异常,请联系管理员"); return commonResp; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。