普通java web项目集成spring-session

之前的老项目,希望使用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管理依赖。

扫描二维码关注公众号,回复: 17410500 查看本文章

优点:目前主流的方式都是通过构建工具管理依赖,很多文档也是针对构建工具写的。对以后升级扩展都比较方便。

缺点:项目比较老,比较大,涉及到的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
	@Primary
	public 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/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">
 
	<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 {

	@Override
	protected 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.总结

涉及到修改的文件有: