一、异常映射

1. 目标:

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

2. 思路:

未命名图片.png
统一管理项目中的异常:

  • 抛出异常
  • 显示异常信息
    • 普通请求:在页面上显示异常信息
    • Ajax请求:返回Json数据

注意:SpringMVC 提供了基于XML和基于注解两种异常映射机制。
在springmvc配置文件中有这样的配置

  1. <!--前端发来 /xxx.html请求,跳转到list.jsp页面-->
  2. <!--注:这里的list会被视图解析器控制,/WEB-INF/list.jsp-->
  3. <mvc:view-controller path="/xxx.html" view-name="list"/>

这样的配置就等于controller中的这个

@RequestMapping("/xxx.html")
public String xxx(){
    return "list";
}

但是:

  • 如果是在controller中写的 就需要用注解的方式完成异常映射。当然了xml同时也生效
  • 如果是在xml中配置 view-controller 就需要用xml的方式完成异常映射

3. 基于xml的方式 异常映射

在spring-mvc的配置文件中配置
配置完后,如果controller中出现了异常,就会跳转到 system-error 页面,此页面被视图解析器拼串

<!--配置基于xml的异常处理映射-->
<bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <!--配置异常的类型和具体视图页面的对应关系-->
  <property name="exceptionMappings">
    <props>
      <!--key属性指定异常全类名-->
      <!--注:中间这个system-error是jsp页面,被视图解析器解析-->
      <prop key="java.lang.Exception">system-error</prop>
    </props>
  </property>
</bean>

4. 基于注解方式 异常映射 准备工作

判断请求类型【普通请求,ajax请求】的工具方法

  1. 添加依赖【如果有则不需要】

    <!-- 引入 Servlet 容器中相关依赖 -->
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
    </dependency>
    
  2. 判断依据

未命名图片.png

  1. 创建工具类,编写方法 ```java import javax.servlet.http.HttpServletRequest;

/**

  • @date: 2021/1/11 17:38
  • @author: 易学习 */ public class CrowdUtil {

    /**

    • 判断请求是普通请求还是ajax请求的工具方法
    • @param request 请求对象
    • @return
    • true: 表示是ajax请求
    • false: 表示是普通请求 */ public static boolean judgeRequestType(HttpServletRequest request){ // 获取请求消息头 String acceptHeader = request.getHeader(“Accept”); String xRequestHeader = request.getHeader(“X-Requested-With”); // 判断 并返回 return (
      (acceptHeader != null && acceptHeader.contains("application/json")) ||
              (xRequestHeader != null && xRequestHeader.equals("XMLHttpRequest")));
      
      } } ```
  1. 测试一波
    @RequestMapping("/xxx.html")
    public void xxx(HttpServletRequest request){
     boolean b = CrowdUtil.judgeRequestType(request);
     System.out.println(b?"ajax":"普通请求");
    }
    

    5. 基于注解方式 异常映射

    创建统一异常处理类
    这里需要依赖一手 CrowdUtil类 来判断请求是ajax还是普通请求 ```java /**
    • @date: 2021/1/11 18:37
    • @author: 易学习
    • 基于注解的异常映射
    • @ControllerAdvice: 表示当前这个类是一个异常处理器类【基于注解】
    • @ExceptionHandler: 将一个具体的异常类型和一个方法关联起来 /

@ControllerAdvice public class CrowdExceptionResolver { /**

 * 空指针异常处理
 * @param exception 
 * @param request
 * @param response
 * @return
 * @throws IOException
 */
@ExceptionHandler(NullPointerException.class)
public ModelAndView resolverNullPointException(NullPointerException exception,
                                               HttpServletRequest request,
                                                HttpServletResponse response
                                                ) throws IOException {
    String viewError = "system-error";
    ModelAndView modelAndView = commonResolve(viewError, exception, request, response);
    return modelAndView;
}

/**
 * 通用异常处理模板
 * @param viewName 异常处理完成后要去的页面
 * @param e  实际捕获的异常
 * @param request 当前的请求对象
 * @param response 当前的响应对象
 * @return
 * @throws IOException
 */
private ModelAndView commonResolve(String viewName,
                                   Exception e,
                                   HttpServletRequest request,
                                   HttpServletResponse response

                                    ) throws IOException {

    // 1.判断请求的类型,如果是普通请求就返回页面,如果是ajax就返回提示错误的json
    boolean judgeRequest = CrowdUtil.judgeRequestType(request);
    // 2.如果是AJAX请求,直接返回null
    if (judgeRequest){
        // 3.创建ResultEntity对象,
        ResultEntity<Object> failed = ResultEntity.failed(e.getMessage());
        // 4.转成JSON  创建gson对象
        Gson gson = new Gson();
        // 5.调用toJson() 方法 转换成Json字符串
        String json = gson.toJson(failed);
        // 6.将json字符串返回给浏览器
        response.getWriter().write(json);
        // 7.上面通过原生的response对象,所以不提供ModelAndView对象了
        return null;
    }
    // 8.如果不是AJax请求,则创建ModelAndView对象
    ModelAndView modelAndView = new ModelAndView();
    // 9.将异常对象放到model中
    modelAndView.addObject("exception",e);
    // 10.设置对应的视图名称
    modelAndView.setViewName(viewName);

    // 11. 返回modelAndView对象
    return modelAndView;

}

}


<a name="VZeI6"></a>
# 二、常量类
```java
package com.yixuexi.crowd.util.constant;

/**
 * @date: 2021/1/11   21:47
 * @author: 易学习
 */
public class CrowdConstant {
    public static final String MESSAGE_LOGIN_FAILED = "抱歉!账号密码错误!请重新输入!";
    public static final String MESSAGE_LOGIN_ACCT_ALREADY_IN_USR = "抱歉!这个账号已经被使用了!";
    public static final String MESSAGE_ACCESS_FORBIDDEN = "请登录以后再访问!";
    public static final String MESSAGE_STRING_INVALID = "字符串无效!";
    public static final String MESSAGE_ACCT_IS_NULL = "账号不存在!";
    public static final String MESSAGE_SYSTEM_ERROR_LOGIN_ACCT_NOT_UNIQUE = "数据错误:登录用户账号不唯一";
    public static final String MESSAGE_DELETE_ONESELF_ERROR = "请勿删除自己!";
    public static final String MESSAGE_ROLE_IS_EXISTS = "角色已存在!";
    public static final String MESSAGE_ACCESS_ERROR="抱歉,您不能访问这个资源!";
    public static final String MESSAGE_CODE_NOT_EXISTS = "验证码已过期!请检查手机号是否正确或重新发送";
    public static final String MESSAGE_CODE_NOT_ERROR = "验证码错误!";


    public static final String ATTR_NAME_LOGIN_ADMIN = "loginAdmin";
    public static final String ATTR_NAME_EXCEPTION = "exception";
    public static final String ATTR_NAME_PAGE_INFO = "pageInfo";
    public static final String ATTR_NAME_MESSAGE = "message";
    public static final String ATTR_NAME_LOGIN_MEMBER = "loginMember";

    public static final String REDIS_CODE_PREFIX = "REDIS_CODE_PREFIX_";

}