背景
在 springmvc 的 controller 中程序员经常要封装错误对象返回错误, 前端显示错误文案. 通过 spring 的异常处理器, 来进行自定义异常处理
学习目标
学习全局异常拦截器处理 controller 所有的异常的返回封装
定义枚举异常码, 设计自定义异常
案列
创建枚举异常码, 定义系统异常情况
- /**
- * @author tianjz
- */
- public enum ResultEnum {
- SUCCESS("0", "成功"),
- PARAMETER_ERROR("1000", "请求参数错误"),
- UNKNOWN_DATA_FORMAT("1001", "未知数据格式"),
- UNDEFINED("1002", "未定义或者错误的接口"),
- ERROR("2000", "响应错误"),
- EMPTY("2001", "空数据");
- private String code;
- private String msg;
- ResultEnum(String code, String msg) {
- this.code = code;
- this.msg = msg;
- }
- public String getCode() {
- return code;
- }
- public String getMsg() {
- return msg;
- }
- }
- import com.cms2.imitative.commons.ResultEnum;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- /**
- * @author tianjz
- */
- @Data
- @AllArgsConstructor
- public class StudyRuntimeException extends RuntimeException {
- /**
- * 异常码
- */
- private ResultEnum errorCode;
- /**
- * 异常描述
- */
- private String errorMessage;
- /**
- * Constructs a new runtime exception with {@code null} as its
- * detail message. The cause is not initialized, and may subsequently be
- * initialized by a call to {@link #initCause}.
- */
- public StudyRuntimeException(ResultEnum errorCode) {
- this.errorCode = errorCode;
- }
- }
具体拦截逻辑 :
通过异常 instanceof 判断出自定义异常
取出异常码, 通过 JSON 方式返回给前端
具体拦截流程:
springboot :< 不要忘记注入 >
springmvc :
请在 xml 中自行注入
- import com.alibaba.fastjson.JSONObject;
- import com.cms2.imitative.commons.ResultEnum;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.HandlerExceptionResolver;
- import org.springframework.Web.servlet.ModelAndView;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.util.LinkedHashMap;
- import java.util.Map;
- /**
- * @author tianjz
- */
- @Component
- @Slf4j
- public class GlobalExceptionInterceptor implements HandlerExceptionResolver {
- @Override
- public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
- ModelAndView view = new ModelAndView();
- Home("全局异常拦截");
- try {
- if (e instanceof StudyRuntimeException) {
- setJsonErrorResponse(response, ((StudyRuntimeException) e).getErrorCode());
- } else {
- setJsonErrorResponse(response, ResultEnum.ERROR);
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- log.error("全局异常捕获失败, 原因 :{},{}",ex.getMessage(),GlobalExceptionInterceptor.class);
- return null;
- }
- return view;
- }
- private void setJsonErrorResponse(HttpServletResponse response, ResultEnum error) throws IOException {
- Map<String, String> map = new LinkedHashMap<>();
- // 设置状态码
- response.setStatus(HttpStatus.OK.value());
- // 设置 ContentType
- response.setContentType(MediaType.APPLICATION_JSON_VALUE);
- // 避免乱码
- response.setCharacterEncoding("UTF-8");
- map.put("code", error.getCode());
- map.put("msg", error.getMsg());
- Object JSON = JSONObject.toJSON(map);
- response.getWriter().write(JSON.toString());
- }
- }
demo 代码 :
- /**
- * @author tianjz
- */
- @RestController
- @RequestMapping("/error")
- public class ExceptionTest {
- @GetMapping("/{errorCode}")
- public String test(@PathVariable("errorCode")String error) {
- switch (error) {
- case "1000":
- throw new StudyRuntimeException(ResultEnum.PARAMETER_ERROR);
- case "2001":
- throw new StudyRuntimeException(ResultEnum.EMPTY);
- default:
- System.out.println("啥也没有");
- }
- return null;
- }
- }
测试效果 :
1000
2001
----------------
来源: http://www.jianshu.com/p/bc9067e32892