zoukankan      html  css  js  c++  java
  • SpringMVC异常处理

    目标

    • 使用异常映射机制将整个项目的异常和错误提示进行统一管理。

    思路

    image
    注意:

    • springmvc 提供了基于 xml和注解两种异常映射机制。
    • <mvc:view-controller> 是在xml文件中配置的 , @RequestMapping注解。
      image

    配置方式

    基于 xml的

    springmvc 全局配置文件

        <!--配置基于xml 异常处理映射-->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
              id="simpleMappingExceptionResolver">
            <!--配置异常类型和具体页面的对应关系-->
            <property name="exceptionMappings">
                <props>
                    <!--<prop key="异常">页面</prop>
                    key属性指定异常全类名
                    标签体中写对应的视图【这个值要拼写前后缀得到具体的路径】-->
                    <prop key="java.lang.Exception">system-error</prop>
                </props>
            </property>
        </bean>
    

    页面

    <%--从域中取出 exceptiono对象,在进一步访问 message属性就能够显示错误信息。--%>
    ${pageContext.exception.message}
    

    基于注解的

    准备

    • 判断当前请求时 普通请求还是 ajax请求 工具类
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @author zhaokuii11@163.com
     * @create 2021-12-01 20:59
     * @Description 判断请求类型、ajax还是 普通的
     */
    public class CrowdUtil {
        /**
         * 判断当前请求是 ajax还是 普通请求
         * 判断依据:
         * Accept : application/json; charset=utf-8
         * X-requested-with: XMLHttpRequest
         * 只要有一个就可以
         *
         * @param request 请求对象
         * @return Boolean true ajax请求、false 普通请求
         */
        public static boolean judgeRequestType(HttpServletRequest request) {
            //1. 获取请求消息头
            String accept = request.getHeader("Accept");
            String xRequestedwith = request.getHeader("X-requested-with");
            //2. 判断
            if (accept != null && accept.contains("application/json") ||
                    xRequestedwith != null && xRequestedwith.contains("XMLHttpRequest")) {
                return true;
            }
            return false;
        }
    }
    

    ajax 工具类

    
    /**
     * @author zhaokuii11@163.com
     * @create 2021-12-01 20:16
     * @Description 统一整个项目中 Ajax请求返回的结果【未来也可以用户分布式框架各个模块间调用时返回统一类型】
     */
    public class ResultEntity<T> {
        public static final String SUCCESS = "success";
        public static final String FAILED = "failed";
        /**
         * 用来封装当前请去处理的结果是成功还是失败
         */
        private String result;
        /**
         * 请去处理失败时返回的错误信息
         */
        private String message;
        /**
         * 要返回的数据
         */
        private T data;
    
        /**
         * 请求处理成功且不需要返回数据使用的工具方法
         * 【增删改的】
         *
         * @param <Type>
         * @return
         */
        public static <Type> ResultEntity<Type> successWithoutData() {
            return new ResultEntity<Type>(SUCCESS, null, null);
        }
    
        /**
         * 请求处理成功且需要返回数据的方法
         * 【查询的】
         *
         * @param data   要返回的数据
         * @param <Type>
         * @return
         */
        public static <Type> ResultEntity<Type> successWithData(Type data) {
            return new ResultEntity<Type>(SUCCESS, null, data);
        }
    
        /**
         * 请求处理失败使用的工具方法
         * 【失败的】
         *
         * @param message 失败的错误消息
         * @param <Type>
         * @return
         */
        public static <Type> ResultEntity<Type> failed(String message) {
            return new ResultEntity<Type>(FAILED, message, null);
        }
    
        public ResultEntity() {
        }
    
        public ResultEntity(String result, String message, T data) {
            this.result = result;
            this.message = message;
            this.data = data;
        }
    
        @Override
        public String toString() {
            return "ResultEntity{" +
                    "result='" + result + '\'' +
                    ", message='" + message + '\'' +
                    ", data=" + data +
                    '}';
        }
    
        public String getResult() {
            return result;
        }
    
        public void setResult(String result) {
            this.result = result;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    }
    

    编写

    import com.aiguigu.crowd.util.CrowdUtil;
    import com.aiguigu.crowd.util.ResultEntity;
    import com.google.gson.Gson;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @author zhaokuii11@163.com
     * @create 2021-12-01 21:14
     * @Description
     */
    //@ControllerAdvice 表示当前类是一个基于注解的异常处理类
    @ControllerAdvice
    public class CrowdExceptionResolver {
    
        //    @ExceptionHandler 将一个具体的异常类型和一个方法关联起来【里面是一个数组】
        @ExceptionHandler(value = NullPointerException.class)
        public ModelAndView resolveNullPointException(
                //实际捕获的德类型
                NullPointerException exception,
                //当前请求对象
                HttpServletRequest request,
                //当前响应对象
                HttpServletResponse response) throws IOException {
    
            //1. 判断当前请去
            boolean requestType = CrowdUtil.judgeRequestType(request);
            //2. 如果 Ajax请求
            if (requestType) {
                //3. 创建 ResultEntity 对象
                ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
                //4. 消息转为 json对象,创建 gson对象
                Gson gson = new Gson();
                //5. 将 json字符串作为响应体返回给浏览器
                String json = gson.toJson(resultEntity);
                //6. 将 json字符串作为响应体返回给浏览器
                response.getWriter().print(json);
                //7. 由于上面通过原生的 response对象返回了响应,所以不提供 modelAndView对象
                return null;
            }
            //8. 如果不是 Ajax请去则创建 ModelAndView对象
            ModelAndView view = new ModelAndView();
            //9. 将 exception对象存入模型
            view.addObject("exception", exception);
            //10. 设置对应的视图
            view.setViewName("system-error");
            //11. 返回
            return view;
        }
    
        /**
         * 抽取公共代码
         *
         * @param viewName  发生异常要去的页面
         * @param exception 发生的异常
         * @param request
         * @param response
         * @return
         * @throws IOException
         */
        private ModelAndView commonResolve(
                //要去的视图
                String viewName,
                //实际捕获的德类型
                Exception exception,
                //当前请求对象
                HttpServletRequest request,
                //当前响应对象
                HttpServletResponse response) throws IOException {
    
            //1. 判断当前请去
            boolean requestType = CrowdUtil.judgeRequestType(request);
            //2. 如果 Ajax请求
            if (requestType) {
                //3. 创建 ResultEntity 对象
                ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
                //4. 消息转为 json对象,创建 gson对象
                Gson gson = new Gson();
                //5. 将 json字符串作为响应体返回给浏览器
                String json = gson.toJson(resultEntity);
                //6. 将 json字符串作为响应体返回给浏览器
                response.getWriter().print(json);
                //7. 由于上面通过原生的 response对象返回了响应,所以不提供 modelAndView对象
                return null;
            }
            //8. 如果不是 Ajax请去则创建 ModelAndView对象
            ModelAndView view = new ModelAndView();
            //9. 将 exception对象存入模型
            view.addObject("exception", exception);
            //10. 设置对应的视图
            view.setViewName(viewName);
            //11. 返回
            return view;
        }
    
        /**
         * 优化
         *
         * @param exception
         * @param request
         * @param response
         * @return
         * @throws IOException
         */
        @ExceptionHandler(value = ArithmeticException.class)
        public ModelAndView resolveArithmeticException(
                //实际捕获的德类型
                NullPointerException exception,
                //当前请求对象
                HttpServletRequest request,
                //当前响应对象
                HttpServletResponse response) throws IOException {
            return commonResolve("system-error", exception, request, response);
        }
    }
    
  • 相关阅读:
    c#读取XML
    Javascript 自动计算生日
    Thread.currentThread()与setDaeMon(boolean c)方法
    StringBuffer类的delete()方法和deleteCharAt()方法
    getStackTrace()方法使用
    JDBC详解
    eclipse与idea路径不匹配
    Idea导入maven项目不自动识别pom.xml
    IDEA找不到或无法加载主类
    MySQL:主从复制与处从复制同步延迟
  • 原文地址:https://www.cnblogs.com/zk2020/p/15631050.html
Copyright © 2011-2022 走看看