之前的老项目,希望使用spring-session管理会话,存储到redis。
项目环境:eclipse、jdk8、jetty嵌入式启动、非spring项目。
实现思路:
1.添加相关依赖jar。
2.配置redis连接。
3.配置启动spring。
4.配置过滤器,拦截替换HttpSession,使用spring-session的实现。
5.启动测试。
具体操作:
1.添加相关依赖jar。
有2中方式:
一种是将项目转为maven或者gradle等类型项目。如maven,就可以通过配置pom.xml管理依赖。
优点:目前主流的方式都是通过构建工具管理依赖,很多文档也是针对构建工具写的。对以后升级扩展都比较方便。
缺点:项目比较老,比较大,涉及到的jar有170多个。转为maven编写pom比较麻烦。
一种是直接将相关的jar拷贝到lib目录下。
优点:只要知道需要依赖哪些jar,就直接拷贝进去就可以了。操作简单直接。
缺点:不能直接知道需要哪些jar。具体到本次升级,一种比较好的做法是根据文档创建一个maven项目,测试运行通过后,将需要的jar拷贝过去。但以后升级扩展面临类似问题。
本次升级我采用的是第一种方案。希望一劳永逸的解决,同时引入spring。
首先将项目转换为maven项目。具体参考:普通java web项目转为maven项目
然后添加依赖:点击查看官方文档:spring-session基于xml配置
<!-- 添加spring-session-redis依赖 --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>2.6.4</version></dependency><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.1.8.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.3.29</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.29</version></dependency>
需要注意的几个点:
1.根据jdk版本选择对应版本。jdk8对于spring-session-data-redis版本最高为2.X.X。3.X版本要求jdk版本大于jdk8。org.springframework版本最高5.X。6.X版本要求jdk版本大于jdk8。
2.官方文档spring-session-data-redis下面配置了<type>pom</type>,这个要去掉,否则会报找不到类org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration
3.需要添加spring-context依赖,否则注解不生效。虽然我们用的是基于xml配置,但是还是会用到了注解。
2.配置redis连接。
根据官方文件,创建EmbeddedRedisConfig类,并根据实际情况进行修改。
package com.xpl.jfinal;import org.apache.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.web.context.ContextLoaderListener;import com.xpl.util.ConfigUtil;@Configuration
//@Profile("embedded-redis") //取消Profile注解,否则启动时可能不生效
public class EmbeddedRedisConfig {private final Logger logger = Logger.getLogger("");@Bean@Primarypublic LettuceConnectionFactory redisConnectionFactory() {logger.info("连接redis");RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(ConfigUtil.getValue("redis_host"));redisConfig.setPassword(ConfigUtil.getValue("redis_password"));return new LettuceConnectionFactory(redisConfig);}}
注意:@Profile注解可能导致项目启动时配置不生效。在这里我们直接注释掉不影响我们使用。
3.配置启动spring。
启动spring需要我们配置spring的上下文和配置web.xml。
首先创建spring的配置文件。/WEB-INF/spring/session.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><bean class="com.xpl.jfinal.EmbeddedRedisConfig"/><bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/><bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/></beans>
注意:官方文档中配置中没有bean com.xpl.jfinal.EmbeddedRedisConfig,导致redis配置没生效。这里需要手动配置下EmbeddedRedisConfig。
然后配置web.xml
<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/session.xml</param-value></context-param>
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
4.配置过滤器。
<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><dispatcher>REQUEST</dispatcher><dispatcher>ERROR</dispatcher></filter-mapping>
5.启动测试。
// src/main/java/sample/SessionServlet.java
public class SessionServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {String attributeName = req.getParameter("attributeName");String attributeValue = req.getParameter("attributeValue");req.getSession().setAttribute(attributeName, attributeValue);resp.sendRedirect(req.getContextPath() + "/");}private static final long serialVersionUID = 2878267318695777395L;}
启动测试发现没有加载spring,后面分析得出原因是依赖冲突导致的。以前项目中包含了slf4j-api-1.7.25.jar,引入的spring也依赖slf4j-api-1.7.32。解决办法直接把老的jar依赖删除。然后重新测试成功。
测试其实通过上面方法方法,还可以通过第一次启动登录后,访问需要登录后才有权限访问的页面,此时页面能正常打开,然后关闭应用,重新启动应用,此时再访问需要登录后才有权限访问的页面,如果能正常访问,这说明集成成功,会话保存到redis了,如果提示没有权限,则说明会话未保存到redis。
6.总结
涉及到修改的文件有: