session验证用户是否登录,对未登录用户进行拦截
文章目录
正常情况下,服务器上的资源很多都是需要登入之后才能访问的,这就需要我们在后台配置一个登入检查的拦截器,对于没有登入的用户跳转到指定的提示页面。
1、编写好一个拦截器类 loginIntercepter.java。注意:从session中获取的对象要和登入时存储到session中的对象一致。
//使用已经实现过的类来实现HandlerInterceptor接口,这样可以实现其中部分的方法。
public class LoginInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 1.通过 request 对象获取 Session 对象
HttpSession session = request.getSession();
// 2.尝试从 Session 域中获取 Admin 对象
Admin admin = (Admin)
session.getAttribute(CrowdConstant.ATT_NAME_LOGIN_ADMIN);
// 3.判断 admin 对象是否为空
if(admin==null)
{
// 4.抛出异常
throw new AccessForbiddenException(CrowdConstant.MESSAGE_ACCESS_FORBIDEN);
}
// 5.如果 Admin 对象不为 null,则返回 true 放行
return true;
}
}
2、编写一个自定义异常AccessForbiddenException.java
PS:直接生成RuntimeException的父类的构造方法。
/**
* 用户未登入时抛出的异常。
* @author tyeerth
* @time 2020年3月19日下午10:21:37
*/
public class AccessForbiddenException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
public AccessForbiddenException() {
super();
}
public AccessForbiddenException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public AccessForbiddenException(String message, Throwable cause) {
super(message, cause);
}
public AccessForbiddenException(String message) {
super(message);
}
public AccessForbiddenException(Throwable cause) {
super(cause);
}
}
3、编写一个异常处理类,用来处理抛出的异常。
/ 表明当前类是一个异常处理类。
@ControllerAdvice
public class CrowdExceptionResolver {
// 表示捕获到 Exception 类型的异常对象由当前方法处理
@ExceptionHandler(value = Exception.class)
public ModelAndView resolveException(Exception exception, HttpServletRequest request, HttpServletResponse response)
throws IOException {
// 只是指定当前异常对应的页面即可
String viewName = "system-error";
return commonResolveException(exception, request, response, viewName);
}
/**
* private表示当前类自己使用。 核心异常处理方法
*
* @param exception
* SpringMVC 捕获到的异常对象
* @param request
* 为了判断当前请求是“普通请求”还是“Ajax 请求” 需要传入原生 request 对象
* @param response
* 为了能够将 JSON 字符串作为当前请求的响应数 据返回给浏览器
* @param viewName
* 指定要前往的视图名称
* @return ModelAndView
* @throws IOException
*/
private ModelAndView commonResolveException(Exception exception, HttpServletRequest request,
HttpServletResponse response, String viewName) throws IOException {
// 1.判断当前请求是“普通请求”还是“Ajax 请求”
boolean judgeResult = CrowdUtil.judgeRequestType(request);
// 2.如果是 Ajax 请求
if (judgeResult) {
// 3.从当前异常对象中获取异常信息
String message = exception.getMessage();
// 4.创建 ResultEntity
ResultEntity<Object> resultEntity = ResultEntity.failed(message);
// 5.创建 Gson 对象
Gson gson = new Gson();
// 6.将 resultEntity 转化为 JSON 字符串
String json = gson.toJson(resultEntity);
// 7.把当前 JSON 字符串作为当前请求的响应体数据返回给
// 浏览器
// ①获取 Writer 对象
PrintWriter writer = response.getWriter();
// ②写入数据
writer.write(json);
// 如果不是Ajax请求,就进行下面的操作。
// 8.返回 null,不给 SpringMVC 提供 ModelAndView 对象
// 这样 SpringMVC 就知道不需要框架解析视图来提供响应,
// 而是程序员自己提供了响应
return null;
}
// 9.创建 ModelAndView 对象
ModelAndView modelAndView = new ModelAndView();
// 10.将 Exception 对象存入模型
modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);
// 11.设置目标视图名称
modelAndView.setViewName(viewName);
// 12.返回 ModelAndView 对象
return modelAndView;
}
}
4、在springMVC的配置文件中加入拦截器,用来配置登入检查
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- mvc:mapping 配置要拦截的资源 -->
<!-- /*对应一层路径,比如:/aaa -->
<!-- /**对应多层路径,比如:/aaa/bbb 或/aaa/bbb/ccc 或/aaa/bbb/ccc/ddd -->
<mvc:mapping path="/**" />
<!-- mvc:exclude-mapping 配置不拦截的资源 -->
<mvc:exclude-mapping path="/admin/to/login/page.html" />
<mvc:exclude-mapping path="/admin/do/login.html" />
<mvc:exclude-mapping path="/admin/do/logout.html" />
<!-- 配置拦截器类 -->
<bean class="com.crowd.mvc.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>