Spring Session

Cookie

Cookie是网络编程中使用最广泛的一项技术,主要用于辨识用户身份

客户端与网站服务端通讯过程如下:

在这里插入图片描述
从图可以看出服务端既要返回Cookie,也要读取客户端提交的Cookie

读Cookie

使用注解读cookie:
如果知道了cookie的值则就可以通过注解的方式读取,不再需要遍历cookie数组

control类的方法增加一个@CookieValue("xxxx") String xxxx参数即可系统会自动解析并传入同名的cookie

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

@RequestMapping("/songlist")
//JSESSIONID为注解名
public Map index(@CookieValue("JSESSIONID") String jSessionId) {
  Map returnData = new HashMap();
  returnData.put("result", "this is song list");
  returnData.put("author", songAuthor);
  returnData.put("JSESSIONID", jSessionId);

  return returnData;
}

写Cookie

为control类的方法增加一个HttpServletResponse参数,调用response.addCookie()方法添加Cookie实例对象即可

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

@RequestMapping("/songlist")
public Map index(HttpServletResponse response) {
  Map returnData = new HashMap();
  returnData.put("result", "this is song list");
  returnData.put("name", songName);

  Cookie cookie = new Cookie("sessionId","CookieTestInfo");
  // 设置的是 cookie 的域名,就是会在哪个域名下生成 cookie 值
  cookie.setDomain("youkeda.com");
  // 是 cookie 的路径,一般就是写到 / ,不会写其他路径的
  cookie.setPath("/");
  // 设置cookie 的最大存活时间,-1 代表随浏览器的有效期,也就是浏览器关闭掉,这个 cookie 就失效了。
  cookie.setMaxAge(-1);
  // 设置是否只能服务器修改,浏览器端不能修改,安全有保障
  cookie.setHttpOnly(false);
  response.addCookie(cookie);

  returnData.put("message", "add cookie successfule");
  return returnData;
}

Cookie的构造函数,第一个参数是cookie名称,第二个参数是cookie值

Spring Session API

如果把用户ID,登录状态等重要信息放在cookie会带来安全隐患,所以我们采用Session

Session会把重要信息存放在服务端从而避免安全隐患

读操作

与cookie相似,从HttpServletRequest对象中取得HttpSession对象,使用的语句是request.getSession(),但返回的结果不是数组而是对象,在attribute属性中用键值对的形式存储多个数据:session.getAttribute("key")

登录信息类

登录信息实例对象要在网上传输,就必须实现序列化接口Serializable,需要根据具体的需要设计属性:

import java.io.Serializable;

public class UserLoginInfo implements Serializable {
  private String userId;
  private String userName;
}

操作代码:

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();
  returnData.put("result", "this is song list");

  // 取得 HttpSession 对象
  HttpSession session = request.getSession();
  // 读取登录信息
  UserLoginInfo userLoginInfo = (UserLoginInfo)session.getAttribute("userLoginInfo");
  if (userLoginInfo == null) {
    // 未登录
    returnData.put("loginInfo", "not login");
  } else {
    // 已登录
    returnData.put("loginInfo", "already login");
  }

  return returnData;
}

写操作

写入数据则使用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) {
  Map returnData = new HashMap();

  // 假设对比用户名和密码成功
  // 仅演示的登录信息对象
  UserLoginInfo userLoginInfo = new UserLoginInfo();
  userLoginInfo.setUserId("12334445576788");
  userLoginInfo.setUserName("ZhangSan");
  // 取得 HttpSession 对象
  HttpSession session = request.getSession();
  // 写入登录信息
  session.setAttribute("userLoginInfo", userLoginInfo);
  returnData.put("message", "login successfule");

  return returnData;
}

Spring Session配置

Spring Boot提供了编程式的配置文件,主要用于配置Bean,在类上添加@Configuration注解,表示这是一个配置类,系统会自动扫描并处理,在方法上添加@Bean注解,表示把此方法返回的对象实例注册成Bean

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

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

依赖库

<!-- spring session 支持 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-core</artifactId>
</dependency>

配置类

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

  • CookieSerializer:读写Cookie中的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<>());
  }
}

Spring Request 拦截器

Spring提供了统一处理相同逻辑的机制:HandlerInterceptor(拦截器)

创建拦截器

拦截器必须实现HandlerInterceptor接口,可以在三个点进行拦截:

  1. Controller方法执行之前.这是最常用的拦截点,比如是否登录的验证方法
  2. Controller方法执行之后,如记录日志,统计方法执行时间等
  3. 整个请求完成后,不常用的拦截点,比如统计整个请求的执行时间时候用
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class InterceptorDemo 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 {

  }
}

实现WebMvcConfigurer

创建一个类实现WebMvcConfigurer,并实现addInterceptors()方法,用于管理拦截器使用addPathPatterns("/**")表示拦截所有的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(InterceptorRegistry registry) {
    // 多个拦截器组成一个拦截器链
    // 仅演示,设置所有 url 都拦截
    registry.addInterceptor(new UserInterceptor()).addPathPatterns("/**");
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-irony-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值