您的位置:首页 > 理论基础 > 计算机网络

SpringSession使用redis存储HttpSession(共享session)

2017-08-09 13:24 489 查看
web开发中session一直都是做分布式集群应用时需要解决的一个难题,过去解决这个难题的一般方式是从serlvet容器上解决,而现在使用spring session能够很容易的把session存储到第三方存储容器,框架提供了redis、jvm的map、mongo、gemfire、hazelcast、jdbc等多种存储session的容器的方式。 关于SpringSession更多的介绍以及功能,可以到SpringSession的官网上查看,SpringSession官方网站中也给出了简单快速的入门案例,Spring
Session - HttpSession (Quick Start),本文是在此基础上实践后给予总结,以及分享一下我在学习springsession过程中遇到的问题以及解决方法。

Spring Session+Redis案例

1.Redis

Redis版本需要在2.8+以上,本案例使用的是redis-4.0.1.tar.gz(下载地址:redis4.0.1),在CentOS6.5下搭建了redis环境,运行并且监听默认的6379端口。

为了能让redis正常运行起来并且顺利使用客户端连接之前需要注意几点:

启动之前需要修改redis目录下的redis.conf配置文件:

(1)远程主机连接redis服务器

# bind 127.0.0.1 ::1   首先要注释掉这个绑定的ip地址,这是让其他机子能通过网络连接redis的前提。

(2)连接redis服务器的登录问题

# Protected mode is a layer of security protection, in order to avoid that

# Redis instances left open on the internet are accessed and exploited.

#

# When protected mode is on and if:

#

# 1) The server is not binding explicitly to a set of addresses using the

# "bind" directive.

# 2) No password is configured.

#

# The server only accepts connections from clients connecting from the

# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain

# sockets.

#

# By default protected mode is enabled. You should disable it only if

# you are sure you want clients from other hosts to connect to Redis

# even if no authentication is configured, nor a specific set of interfaces

# are explicitly listed using the "bind" directive.

#protected-mode yes

#daemonize no

#requirepass 677714

protected-mode no

这是连接redis服务器时是不是需要登录密码的设置,默认protected-mode的值为true,需要自己加上requirepass作为登录密码。以后客户端连接该服务器时需要使用-a passpw来指定密码验证登录。假设说redis服务器不需要使用密码进行登录,直接将protected-mode设置为false即可。

(3)redis监听端口6379

redis服务端,默认是监听的6379端口,在CentOS安装完redis之后,需要开放6379端口(记得重启才生效)。不然外网主机是连接不上redis服务端的。

启动redis服务端:



默认启动时会自动加载redis目录下的redis.conf配置文件,如果想指定conf文件进行启动,可以直接使用redis-server  conf文件路径 命令即可。

开启redis客户端连接一下测试:



2. JAVA API(集成spring session)

springsession 的源代码下载地址:springsession1.31

在里面的sample目录下有spring session的demo,包括官方说明案例的源代码。

(1)使用Maven来够构建项目,依赖的porm.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>cn.eboy</groupId>
<artifactId>testspringtest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>testspringtest Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- spring session-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>3.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>

<!-- web -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.5</version>
<scope>provided</scope>
</dependency>

<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>testspringtest</finalName>
</build>
</project>

(2)配置连接redis:

package sample;

import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@EnableRedisHttpSession
public class Config {
@Bean
public LettuceConnectionFactory connectionFactory() {

LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory();

lettuceConnectionFactory.setHostName("192.168.199.100");
lettuceConnectionFactory.setPort(6379);
//lettuceConnectionFactory.setPassword("677714");
return lettuceConnectionFactory;
}
}


(3)java servlet容器初始化

package sample;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;

public class Initializer extends AbstractHttpSessionApplicationInitializer {
public Initializer() {
super(Config.class);
}
}
(4)创建一个session应用

main.jsp:

<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Session Attributes</title>
<style type="text/css">
body {
padding: 1em;
}
</style>
</head>
<body>
<div class="container">
<h1>Description</h1>
<p>This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.</p>

<h1>Try it</h1>

<form action="testspringtest/session" method="post">
<label for="attributeName">Attribute Name</label>
<input id="attributeName" type="text" name="attributeName"/>
<label for="attributeValue">Attribute Value</label>
<input id="attributeValue" type="text" name="attributeValue"/>
<input type="submit" value="Set Attribute"/>
</form>

<hr/>

<table class="table table-striped">
<thead>
<tr>
<th>Attribute Name</th>
<th>Attribute Value</th>
</tr>
</thead>
<tbody>
<c:forEach items="${sessionScope}" var="attr">
<tr>
<td><c:out value="${attr.key}"/></td>
<td><c:out value="${attr.value}"/></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</body>
</html>


servlet:

package sample;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/testspringtest/session")
public class SessionServlet extends HttpServlet {

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String attributeName = req.getParameter("attributeName");
String attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);
String path=req.getContextPath() + "/main.jsp";
resp.sendRedirect(path);
}

private static final long serialVersionUID = 2878267318695777395L;
}


(5)测试

1.首先清空redis队列

127.0.0.1:6379> flushall

OK

127.0.0.1:6379> keys *

(empty list or set)

2.运行应用程序创建session



连接redis服务端,查看所有键值对:

[root@centos-server-yzr yzr]# redis-cli -h 127.0.0.1 -p 6379

127.0.0.1:6379> keys *

1) "spring:session:expirations:1502257200000"

2) "spring:session:sessions:expires:9aca7aef-5b8c-40f0-b5c1-78e57c4cab96"

3) "spring:session:sessions:9aca7aef-5b8c-40f0-b5c1-78e57c4cab96"

127.0.0.1:6379>

查看浏览器cookie:



在redis客户端输入HGETALL来查看spring session具体的值:



删除redis中的数据:

$ redis-cli del spring:session:sessions:9aca7aef-5b8c-40f0-b5c1-78e57c4cab96

这样在应用程序中的session也就被删除掉了。

测试总结:HttpSession的数据都保存到redis中去了,这样操作httpsession数据的话直接操作redis就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: