spring session

1. Cookie

在这里插入图片描述
主要分析服务端 Spring 工程是如何使用 Cookie 的,有读、写两种操作

1.1 读Cookie

Control 类的方法增加一个HttpServletRequest参数,通过request.getCookies()取得cookie数组,然后再循环遍历数组即可
系统会自动传入方法参数所需要的的HttpServletRequest对象

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

@RestController
public class SongListControl {
	//从配置文件中读取自定义的配置项
	@Value("${song.author}")
	private String songAuthor;

	@RequestMapping("/songlist")
	public Map index(HttpServletRequest request) {
		Map returnData = new HashMap();
		returnData.put("result", "this is song list");
		returnData.put("author", songAuthor);
		Cookie[] cookies = request.getCookies();
		returnData.put("cookies", cookies);
		return returnData;
	}
}
1.2 使用注解读取 Cookie

必须要知道 cookie 的名字,才可以使用。
control类的方法增加一个@CookieValue("xxxx") String xxxx参数即可,系统会自动解析并传入同名的 cookie

import org.springframework.web.bind.annotation.CookieValue;

******(省略)******
@RequestMapping("/songlist")
public Map index(@CookieValue("JSESSIONID") String jSessionId) {
	Map returnData = new HashMap();
	returnData.put("result", "this is song list");
	returnData.put("JSESSIONID", jSessionId);
	return returnData;
}

如果系统解析不到指定名字的 Cookie,使用此注解就会报错

1.3 写 Cookie

control类的方法增加一个HttpServletResponse参数,调用response.addCookie()方法添加Cookie实例对象。
系统会自动传入方法参数所需要的HttpServletResponse对象

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

@RequestMapping("/songlist")
public Map index(HttpServletResponse response) {
	Cookie cookie = new Cookie("sessionId", "CookieTestInfo");
	//设置的是 cookie 的域名,就是会在哪个域名下生成 cookie 值
	cookie.setDomain("*****");
	//设置的是 cookie 的路径,一般就是写到 / ,不会写其他路径的
	cookie.setPath("/");
	//设置 cookie 的最大存活时间,-1代表随浏览器的有效期
	cookie.setMaxAge(-1);
	//设置是否只能服务器修改,浏览器端不能修改
	cookie.setHttpOnly(false);
	response.addCookie(cookie);
	return new HashMap();
}

2. Spring Session API

采用 Session 会话机制将用户ID登录状态等重要信息放在服务端,避免安全隐患
在这里插入图片描述
使用会话机制时,Cookie 作为 session id 的载体与客户端通信。上面文章中的代码中,Cookie 中的 JSESSIONID就是这个作用。
名字为 JSESSIONID 的cookie,是专门用来记录用户 session 的。JSESSIONID 是标准的、通用的名字

2.1 读操作

HttpServletRequest对象中取得HttpSession对象,使用的语句是request.getSession()。返回的不是数组而是对象。在 attribute属性中用 key --> value 的形式存储多个数据。
假设存储登录信息的数据 keyuserLoginInfo,那么语句就是session.getAttribute("userLoginInfo")
登录信息类:
登录信息实例对象因为要在网络上传输,就必须实现序列接口Serializable,否则会报错

import java.io.Serializable;
public class UserLoginInfo implements Serializable {
	private String userId;
	private String userName;
	//get、set方法省略
}

操作代码

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@RequestMapping("/songlist")
public Map index(HttpServletRequest request, HttpServletResponse response) {
	Map returnData = new HashMap();
	//取得 HTTPSession 对象
	HttpSession session = request.getSession();
	//读取登录信息(取出来的为Object类型,要进行强制转换)
	UserLoginInfo userLoginInfo = (UserLoginInfo) session.getAttribute("userLoginInfo");
	if (userLoginInfo == null) {
		//未登录
	} else {
		//已登录
	}
	return new HashMap();
}
2.2 写操作

假设登录成功,如何记录登录信息到 Session 呢?
写入信息用setAttribute()方法

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@RequestMapping("/loginmock")
public Map loginMock(HttpServletRequest request, HttpServletResponse response) {
	UserLoginInfo userLoginInfo = new UserLoginInfo();
	userLoginInfo.setUserId("12345");
	userLoginInfo.setUserName("hahah");
	//取得 HttpSession 对象
	HttpSession session = request.getSession();
	//写入登录信息
	session.setAttribute("userLoginInfo", userLoginInfo);
	return new HashMap();
}

3. Spring Session 配置

上面代码中,没有涉及 cookie,系统会自动把默认的JSESSIONID放在默认的cookie中。但 Cookie 作为 session id 的载体,也可以修改属性
配置
application.propertiesSpringBoot的标准配置文件,配置一些简单的属性,同时,Spring Boot也提供了编程式的配置方式,主要用于配置Bean

基本格式:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringHttpSessionConfig {
	@Bean
	public TestBean testBean() {
		return new TestBean();
	}
}

在类上添加@Configuration注解,就表示这是一个配置类,系统会自动扫描并处理,在方法上添加@Bean注解,表示把此方法返回的对象实例注册成Bean

3.1 Session 配置
3.1.1 依赖库
<!-- spring session 支持 -->
<dependency>
  <groupId>org.springframework.session</groupId>
   <artifactId>spring-session-core</artifactId>
</dependency>
3.1.2 配置类

在类上额外加一个注解:@EnableSpringHttpSession,开启session。然后,注册两个Bean:

  • CookieSerializer:读写 Cookies 中的 SessionId 信息
  • MapSessionRepository:Session 信息在服务器上的存储仓库
import org.springframework.session.MapSessionRepository;
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
import java.util.concurrent.ConcurrentHashMap;

@Configuration
@EnableSpringHttpSession
public class SpringHttpSessionConfig {
	@Bean
	public CookieSerializer cookieSerializer() {
		DefaultCookieSerializer serializer = new DefaultCookieSerializer();
		serializer.setCookieName("JSESSIONID");
		//用正则表达式配置匹配的域名,可以兼容 localhost、127.0.0.1 等各种场景
		serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
		serializer.setCookiePath("/");
		serializer.setUseHttpOnlyCookie(false);
		//最大生命周期的单位是分钟
		serializer.setCookieMaxAge(24*60*60);
		return serializer;
	}
	
	@Bean
	public MapSessionRepository sessionRepository() {
		return new MapSessionRepository(new ConcurrentHashMap<>());
	}
}

4. Spring Request 拦截器

大量的页面功能是需要判断用户是否登录了

4.1 创建拦截器

拦截器必须实现HandlerInterceptor接口
三个拦截点:

  • Controller方法执行之前。例如是否登录的验证就是在preHandler()方法中处理
  • Controller方法执行之后。例如记录日志、统计方法、执行时间等,就要在postHandler方法中处理
  • 整个请求完成后。例如统计整个请求的执行时间在afterCompletion方法中处理
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class UserInterceptor implements HandlerInterceptor {
	//Controller方法执行之前
	@Override
	public boolean preHandle(HttpServletRequest request, 
	HttpServletResponse response, Object handler) throws Exception {
		//只有返回 true 才会继续向下执行,返回 false 取消当前请求
		return true;
	}
	
	//Controller方法执行之后
	@Override
	public void postHandle(HttpServletRequest request, 
	HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		
	}

	//整个请求完成后(包括 Thymeleaf 渲染完毕)
	@Override
	public void afterCompletion(HttpServletRequest request, 
	HttpServletResponse response, Object handler, Exception ex) throws Exception {
	
	}
}
4.2 实现 WebMvcConfigurer

创建一个类实现WebMvcConfigurer, 并实现addInterceptors()方法,,这个步骤用于管理拦截器。
实现类上要加上@Configuration注解,让框架能自动扫描并处理
管理拦截器,比较重要的是拦截设置拦截范围,常用addPathPatterns("/**")表示拦截所有的 URL,可以调用excludePathPatterns()方法排除某些 URL,例如登录页本身就不需要登录,需要排除。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebAppConfigurerDemo implements WebMvcConfigurer {

	@Override
	public void addInterceptors(InterceptoryRegistry registry) {
		//多个拦截器组成一个拦截器链
		registry.addInterceptor(new UserInterceptor()).addPathPatterns("/**");
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值