一、异常映射
1. 目标:
使用异常映射机制,将整个项目的异常和错误提示进行统一的管理。
2. 思路:
统一管理项目中的异常:
- 抛出异常
- 显示异常信息
- 普通请求:在页面上显示异常信息
- Ajax请求:返回Json数据
注意:SpringMVC 提供了基于XML和基于注解两种异常映射机制。
在springmvc配置文件中有这样的配置
<!--前端发来 /xxx.html请求,跳转到list.jsp页面-->
<!--注:这里的list会被视图解析器控制,/WEB-INF/list.jsp-->
<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请求】的工具方法
添加依赖【如果有则不需要】
<!-- 引入 Servlet 容器中相关依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency>
判断依据
- 创建工具类,编写方法 ```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")));
- 测试一波
@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_";
}