原创转载请注明出处:http://agilestyle.iteye.com/blog/2384372
Project Directory
Maven Dependency
<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>org.fool.springredis</groupId> <artifactId>spring-redis</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>spring-redis Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.3.1.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.9</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.42</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/</path> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build> </project>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> </web-app>
Spring Configuration
root-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <context:component-scan base-package="org.fool.springredis"/> <!-- 连接池配置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大连接数 --> <property name="maxTotal" value="30"/> <!-- 最大空闲连接数 --> <property name="maxIdle" value="10"/> <!-- 每次释放连接的最大数目 --> <property name="numTestsPerEvictionRun" value="1024"/> <!-- 释放连接的扫描间隔(毫秒) --> <property name="timeBetweenEvictionRunsMillis" value="30000"/> <!-- 连接最小空闲时间 --> <property name="minEvictableIdleTimeMillis" value="1800000"/> <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 --> <property name="softMinEvictableIdleTimeMillis" value="10000"/> <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 --> <property name="maxWaitMillis" value="1500"/> <!-- 在获取连接的时候检查有效性, 默认false --> <property name="testOnBorrow" value="true"/> <!-- 在空闲时检查有效性, 默认false --> <property name="testWhileIdle" value="true"/> <!-- 连接耗尽时是否阻塞, false报异常, true阻塞直到超时, 默认true --> <property name="blockWhenExhausted" value="false"/> </bean> <!--Spring Session Redis配置--> <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <!-- 过期时间10分钟 --> <property name="maxInactiveIntervalInSeconds" value="600"/> </bean> <bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="192.168.121.128"/> <property name="password" value=""/> <property name="port" value="6379"/> <property name="poolConfig" ref="jedisPoolConfig"/> </bean> <!--single--> <bean id="jedisPool" class="redis.clients.jedis.JedisPool"> <constructor-arg name="host" value="192.168.121.128"/> <constructor-arg name="port" value="6379"/> <constructor-arg name="poolConfig" ref="jedisPoolConfig"/> </bean> <bean id="jedisClient" class="org.fool.springredis.dao.impl.JedisClientSingle"/> <!--cluster--> <!--<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">--> <!--<constructor-arg>--> <!--<set>--> <!--<bean class="redis.clients.jedis.HostAndPort">--> <!--<constructor-arg name="host" value="192.168.121.128"/>--> <!--<constructor-arg name="port" value="7001"/>--> <!--</bean>--> <!--<bean class="redis.clients.jedis.HostAndPort">--> <!--<constructor-arg name="host" value="192.168.121.128"/>--> <!--<constructor-arg name="port" value="7002"/>--> <!--</bean>--> <!--<bean class="redis.clients.jedis.HostAndPort">--> <!--<constructor-arg name="host" value="192.168.121.128"/>--> <!--<constructor-arg name="port" value="7003"/>--> <!--</bean>--> <!--<bean class="redis.clients.jedis.HostAndPort">--> <!--<constructor-arg name="host" value="192.168.121.128"/>--> <!--<constructor-arg name="port" value="7004"/>--> <!--</bean>--> <!--<bean class="redis.clients.jedis.HostAndPort">--> <!--<constructor-arg name="host" value="192.168.121.128"/>--> <!--<constructor-arg name="port" value="7005"/>--> <!--</bean>--> <!--<bean class="redis.clients.jedis.HostAndPort">--> <!--<constructor-arg name="host" value="192.168.121.128"/>--> <!--<constructor-arg name="port" value="7006"/>--> <!--</bean>--> <!--</set>--> <!--</constructor-arg>--> <!--<constructor-arg name="poolConfig" ref="jedisPoolConfig"/>--> <!--</bean>--> <!--<bean id="jedisClientCluster" class="org.fool.springredis.dao.impl.JedisClientCluster"/>--> </beans>
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven/> <mvc:resources location="/resources/" mapping="/resources/**"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <context:component-scan base-package="org.fool.springredis"/> </beans>
Java Classes
User.java
package org.fool.springredis.model; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; public class User { private String username; private String password; public User() { } public User(String username, String password) { this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
JsonUtil.java
package org.fool.springredis.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; import java.util.Map; public class JsonUtil { private static final ObjectMapper MAPPER = new ObjectMapper(); public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List<T> list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); } return null; } public static <K, V> Map<K, V> jsonToMap(String jsonData, Class<K> keyType, Class<V> valueType) { JavaType javaType = MAPPER.getTypeFactory().constructMapType(Map.class, keyType, valueType); try { Map<K, V> map = MAPPER.readValue(jsonData, javaType); return map; } catch (Exception e) { e.printStackTrace(); } return null; } }
JedisClient.java
package org.fool.springredis.dao; public interface JedisClient { String get(String key); String set(String key, String value); String hget(String hkey, String key); long hset(String hkey, String key, String value); long incr(String key); long expire(String key, int second); long ttl(String key); long del(String key); long hdel(String hkey, String key); }
JedisClientSingle.java
package org.fool.springredis.dao.impl; import org.fool.springredis.dao.JedisClient; import org.springframework.beans.factory.annotation.Autowired; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class JedisClientSingle implements JedisClient { @Autowired private JedisPool jedisPool; @Override public String get(String key) { Jedis jedis = jedisPool.getResource(); String result = jedis.get(key); jedis.close(); return result; } @Override public String set(String key, String value) { Jedis jedis = jedisPool.getResource(); String result = jedis.set(key, value); jedis.close(); return result; } @Override public String hget(String hkey, String key) { Jedis jedis = jedisPool.getResource(); String result = jedis.hget(hkey, key); jedis.close(); return result; } @Override public long hset(String hkey, String key, String value) { Jedis jedis = jedisPool.getResource(); long result = jedis.hset(hkey, key, value); jedis.close(); return result; } @Override public long incr(String key) { Jedis jedis = jedisPool.getResource(); long result = jedis.incr(key); jedis.close(); return result; } @Override public long expire(String key, int second) { Jedis jedis = jedisPool.getResource(); long result = jedis.expire(key, second); jedis.close(); return result; } @Override public long ttl(String key) { Jedis jedis = jedisPool.getResource(); long result = jedis.ttl(key); jedis.close(); return result; } @Override public long del(String key) { Jedis jedis = jedisPool.getResource(); long result = jedis.del(key); jedis.close(); return result; } @Override public long hdel(String hkey, String key) { Jedis jedis = jedisPool.getResource(); long result = jedis.hdel(hkey, key); jedis.close(); return result; } }
JedisClientCluster.java
package org.fool.springredis.dao.impl; import org.fool.springredis.dao.JedisClient; import org.springframework.beans.factory.annotation.Autowired; import redis.clients.jedis.JedisCluster; public class JedisClientCluster implements JedisClient { @Autowired private JedisCluster jedisCluster; @Override public String get(String key) { return jedisCluster.get(key); } @Override public String set(String key, String value) { return jedisCluster.set(key, value); } @Override public String hget(String hkey, String key) { return jedisCluster.hget(hkey, key); } @Override public long hset(String hkey, String key, String value) { return jedisCluster.hset(hkey, key, value); } @Override public long incr(String key) { return jedisCluster.incr(key); } @Override public long expire(String key, int second) { return jedisCluster.expire(key, second); } @Override public long ttl(String key) { return jedisCluster.ttl(key); } @Override public long del(String key) { return jedisCluster.del(key); } @Override public long hdel(String hkey, String key) { return jedisCluster.hdel(hkey, key); } }
IndexController.java
package org.fool.springredis.controller; import org.apache.commons.lang3.StringUtils; import org.fool.springredis.model.User; import org.fool.springredis.util.JsonUtil; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpServletRequest; @Controller public class IndexController { @GetMapping("/login") public String login() { return "login"; } @PostMapping("/login") public String login(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); request.getSession().setAttribute("user", JsonUtil.objectToJson(new User(username, password))); return "redirect:/index"; } @GetMapping("/index") public String index(HttpServletRequest request, Model model) { String userJsonStr = (String) request.getSession().getAttribute("user"); User user = null; if (StringUtils.isNotBlank(userJsonStr)) { user = JsonUtil.jsonToPojo(userJsonStr, User.class); } model.addAttribute("user", user); return "index"; } }
JSP Pages
login.jsp
<html> <head> <title>login</title> </head> <body> <h2>login page</h2> <form action="/login" method="post"> username:<input type="text" name="username"><br> password:<input type="password" name="password"><br> <input type="submit" value="login"> </form> </body> </html>
index.jsp
<html> <body> <h2>Hello Spring Redis!</h2> <p>${user.username}</p> <p>${user.password}</p> </body> </html>
Test
查看Redis
登录login页面
再次查看Redis
输入username和password,点击login按钮
再次查看Redis
不在页面上做任何操作,静静等待10分钟(本例中Spring Redis Session设置过期时间为600,即10分钟)
再次访问index页面
Reference
http://www.infoq.com/cn/articles/Next-Generation-Session-Management-with-Spring-Session/
相关推荐
本篇文章将深入探讨如何利用Redis实现Session共享,同时结合Nginx的负载均衡策略,以及Spring Boot的应用框架,构建一个高效、可靠的分布式系统。 一、Session共享的挑战与解决方案 在传统的单体应用中,Session...
SSM(Spring、Spring MVC、MyBatis)是Java后端开发的常用框架组合,而Redis是一个高性能的键值数据库,常用于缓存和session存储。Nginx则是一款强大的反向代理服务器,能够实现负载均衡。接下来我们将深入探讨如何...
Spring-boot-shiro-spring-session-redis-example项目启动后输入:该项目中, 增加了对url的拦截,用admin/123456,拥有index权限reports未任何权限, jdonee/123456尚未分配任何权限.参考shiro Cache交于Redis进行管理...
实现`Tomcat`与`Redis`的session共享,需要添加相应的session管理器和依赖jar包,例如`spring-session-data-redis`或`tomcat-redis-session-manager`。 以下是一个使用`spring-session-data-redis`的配置示例: 1....
3. **其他依赖**:虽然主要依赖是Jedis和Tomcat-RedisSessionManager,但在实际项目中,你可能还需要其他相关jar包,如Spring Session框架,它可以简化与Redis的集成,提供更高级别的抽象。如果你使用Spring Boot,...
在Web应用的部署描述符`web.xml`中,需要添加一个名为`springSessionRepositoryFilter`的过滤器,它负责将Session请求代理到Spring Session,确保每次调用`getSession()`时都从Redis获取Session数据。 ```xml ...
在IT行业中,Spring Data Redis是Spring框架的一部分,用于简化Redis数据存储系统的操作。Redis是一种高性能的键值数据库,常用于缓存、消息队列等多种场景。为了增强安全性,Redis支持认证功能,确保只有授权的...
例如,你可以使用`spring-session-data-redis`或`tomcat-redis-session-manager`。这些库提供了处理session持久化的必要工具。 3. **配置`context.xml`**:在Tomcat的`conf`目录下,修改或创建`context.xml`文件,...
接着,在`RedisSessionManager`类中实现Spring Session的`HttpSessionRepository`接口,负责将session数据存入和读取自Redis。 **整合Nginx、Redis和Tomcat** 整合这三个组件,你需要确保Nginx、Redis和Tomcat都在...
在Spring Shiro项目中,Redis可以作为Session的后台存储,将Session数据保存在内存中,提升读取速度,同时解决了单机Session丢失的问题,使得会话在集群中保持一致性。 项目"spring-shiro-redis-example-master...
本解决方案将详细介绍如何在`CentOS7`上配置`Nginx`以实现`Tomcat`的负载均衡,并利用`Redis`进行Session共享,以提高系统的可扩展性和用户会话的一致性。 首先,我们需要在`CentOS7`上安装`Nginx`。可以使用`yum`...
在Tomcat中,可以通过实现`HttpSession`接口的自定义session管理器,或者使用第三方session管理过滤器(如`spring-session-data-redis`)来实现session的Redis存储。 安装和配置过程大致如下: 1. 在Tomcat服务器上...
总结,"Tomcat-Redis-Session-Example"是一个帮助开发者理解和实践如何在Java Web应用中使用Redis进行会话管理的示例项目。通过学习和实施这个示例,开发者可以提升应用的扩展性和可靠性,同时减轻服务器的内存负担...
Spring 会话示例这是一个用于演示的小示例项目。 它由具有单个HelloServlet servlet 的嵌入式 Tomcat 组成。 当发出GET请求时,servlet 将使用默认的Hello World! 或者如果name会话属性已设置为Hello [name] 。 可以...
Example涵盖内容: 4种日志框架详解:Logback、Log4j、Log4j2和Slf4j,基于secure-ext-spring-boot-starter日志记录脱敏,spring-session基于redis存储session,集成MyBatis以及mybatis-plus3的应用实践,安全认证-...
3. 使用`Spring Session`或`Tomcat Redis Session Manager`等库管理`session`存储。 总结,通过`Nginx`实现`Tomcat`集群的负载均衡和`session`共享,不仅可以提高服务的可用性和性能,还能为用户提供一致性的体验。...
- chapter4-3-2:[使用Spring Session(未完成)] #### 缓存支持 - chapter4-4-1:[注解配置与EhCache使用](http://blog.didispace.com/springbootcache1/) - chapter4-4-2:[使用Redis做集中式缓存]...
41. Spring Session 42. Monitoring and Management over JMX 43. Testing 43.1. Test Scope Dependencies 43.2. Testing Spring Applications 43.3. Testing Spring Boot Applications 43.3.1. Detecting Web ...
build.gradle 中指定): org.springframework.boot :用于基础 MVC 框架org.springframework.security :用于各种与安全相关的目的,包括身份验证和散列org.springframework.session :用于用户会话org.hibernate :...
Shiro 提供了原生会话(native-session)机制,允许在不依赖容器的 Session 实现情况下,存储和管理用户的认证信息,这使得它能很好地应用于各种场景,包括 Web 应用、Flex 应用、远程服务调用等。 在整合 Shiro 和...