用户会话session
session对象主要存在服务器端,可以用于保存服务器的临时数据的对象,所保存的数据可以在整个项目中都可以通过访问来获取,把session的数据看做一个共享的数据。首次登陆的时候所获取的用户的数据,转移到session对象即可。session.getAttribute("key")可以将获取session中的数据这种行为进行封装,封装在BaseController类中。
1.封装session对象中数据的获取(封装在父类中)、数据的设置(当用户登录成功后进行数据的设置,设置到全局的session对象)。
2.在父类中封装两个数据:获取uid和获取username对应的两个方法。用户头像暂时不考虑,将来封装在cookie中来使用。
/**
* 获取session对象中的uid
* @param session session对象
* @return 当前登录的用户uid的值
*/
protected final Integer getUidFromSession(HttpSession session){
return Integer.valueOf(session.getAttribute("uid")
.toString());
}
/**
* 获取当前登录用户的username
* @param session session对象
* @return 当前登录用户的用户名称
* 在实现类中重写父类中的toString(),不是句柄信息的输出
*/
protected final String getUsernameFromSession(HttpSession session){
return session.getAttribute("username").toString();
}
3.在登陆的方法中将数据封装在session对象中。 服务器本身自动创建有session对象,已经是一个全局的session对象。SpringBoot直接使用session对象,直接将httpSession类型的对象作为请求处理方法的参数,会自动将全局的session对象注入到请求处理方法的session形参上。
@RequestMapping("login")
public JsonResult<User> login(String username,
String password,
HttpSession session ){
User data = userService.login(username, password);
//向session对象中完成数据的绑定
session.setAttribute("uid",data.getUid());
session.setAttribute("username",data.getUsername());
//获取session中绑定的数据
System.out.println(getUidFromSession(session));
System.out.println(getUsernameFromSession(session));
return new JsonResult<User>(OK,data);
}
拦截器
拦截器:首先将所有的请求统一拦截到拦截器中,可以在拦截器中来定义过滤的规则,如果不满足系统设置的过滤规则,统一的处理是重新去打开login.html页面(重定向和转发),推荐使用重定向。
在SpringBoot项目中拦截器的定义和使用。SpringBoot是依靠SpringMVC来完成的。SpringMVC提供了一个HandlerInterceptor接口,用于表示定义一个拦截器。首先自定义一个类,再让这个类实现这个接口。
1.首先自定义一个类,让这个类实现HandlerInterceptor接口。
package com.cy.store.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**定义一个拦截器**/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 检测全局session对象中是否有uid数据,有则放行,没有则重定向到登陆界面
* @param request 请求对象
* @param response 响应对象
* @param handler 处理器(url+Controller:映射)
* @return 如果返回值为true放行当前的请求,如果为false,则表示拦截当前的请求
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// HttpServletRequest对象来获取session对象
Object obj = request.getSession().getAttribute("uid");
if(obj==null){
//说明用户没有登陆过系统,重定向到login.html界面
response.sendRedirect("/web/login.html");
//结束后续的调用
return false;
}
//请求放行
return true;
}
}
2.注册过滤器:添加白名单(哪些资源可以在不登陆的i情况下访问)、添加黑名单(用户登陆的状态下才能访问的资源)
package com.cy.store.config;
import com.cy.store.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/** 处理器拦截器的注册**/
@Configuration // 加载当前的拦截器并进行注册
public class LoginInterceptorConfigure implements WebMvcConfigurer {
/** 配置拦截器**/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//创建自定义的拦截器对象
HandlerInterceptor interceptor=new LoginInterceptor();
//配置白名单:存放在一个List集合中
List<String> patterns=new ArrayList<>();
patterns.add("/bootstrap3/**");
patterns.add("/css/**");
patterns.add("/images/**");
patterns.add("/js/**");
patterns.add("/web/register.html");
patterns.add("/web/login.html");
patterns.add("/web/index.html");
patterns.add("/web/product.html");
patterns.add("/users/reg");
patterns.add("/users/login");
//完成拦截器的注册
registry.addInterceptor(interceptor).
addPathPatterns("/**")
.excludePathPatterns(patterns); //表示拦截的url是什么
}
}
3.注册拦截器的技术:借助WebMvcConfigure接口,可以将用户定义的拦截器进行注册,才可以保证拦截器能够生效和使用。定义一个类,然后让这个类实现WebMvcConfigure接口。配置信息,建议放在项目的config包结构下。
//将自定义的拦截器进行注册
/** 处理器拦截器的注册**/
public class LoginInterceptorConfigure implements WebMvcConfigurer {
}
4.提示重定向次数过多,login.html页面无法打开。将浏览器cookie清楚,浏览器初始化
源码解析:
public interface HandlerInterceptor {
//在调用所有处理请求的方法之前被自动调用执行的方法
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
// 在ModelAndViex对象返回之后被调用的方法
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
// 在整个请求所有关联的资源被执行完毕最后执行的方法
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}