问题描述
我使用的是 Spring 5.3、Spring session 2.4.x、spring-data-redis 2.4.x 和 Spring security 5.3。我们正在使用一个使用 JSP 的旧应用程序。我们想将会话数据存储在 Redis 中。使用代码片段 <jsp:useBean id="context" scope="session" class="com.xxx.yyy.SessionControl"/>
在 jsp 中使用的所有 bean 都被持久化到 Redis 中。我还有一个会话范围的 bean,创建如下,但这不会持久化到 Redis 中。你能告诉我如何自动将这个 bean 推送到 Redis 中吗?
@Bean
@Scope(value = "session"/*,proxyMode = ScopedProxyMode.TARGET_CLASS */)
public UserCacheData UserCacheData() {
UserCacheData data = new UserCacheData();
return data;
}
此外,我尝试了以下代码将 bean 放入 Session 但这不起作用,因为使用此方法获得的 session-id(下面代码中的 id1、id2 和 id3)与实际 servlet 请求的会话 id 不同(从org.springframework.session.web.http.SessionRepositoryFilter<S>
获得)
@Autowired
ObjectFactory<HttpSession> httpSessionFactory;
@Autowired
private HttpSession httpSession;
@Autowired
public RedisIndexedSessionRepository sessionRepository;
public static HttpSession currentSession() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
return attr.getRequest().getSession(false); // true == allow create
}
@Bean
@Scope(value = "session"/*,proxyMode = ScopedProxyMode.TARGET_CLASS */)
public UserCacheData UserCacheData() {
UserCacheData data = new UserCacheData();
HttpSession session = currentSession();
if(null != session) {
String id = session.getId();
String id1 = (null !=httpSessionFactory) ?httpSessionFactory.getobject().getId():"";
String id2 = (null !=httpSession) ?httpSession.getId():"";
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
String id3 = (null != request) ? request.getSession(false).getId():"";
session.setAttribute(UserCacheData.class.getName(),data);
}
return data;
}
Spring 会话配置
import java.io.IOException;
import javax.xml.datatype.XMLGregorianCalendar;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec.ThrowableMixIn;
import org.redisson.config.Config;
import org.redisson.spring.data.connection.RedissonConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.jackson2.CoreJackson2Module;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.session.SaveMode;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.SessionRepositoryFilter;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTypeResolverBuilder;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.test.besystem.bapi.api.CustomDeserializer;
import com.test.besystem.bapi.api.CustomSerializer;
import com.test.besystem.bapi.api.UserCacheData;
import com.test.besystem.bapi.api.UserData;
import com.test.besystem.config.RedisConfig;
/**
* @author dpoddar
*
*/
@Configuration
@EnableRedisHttpSession(saveMode = SaveMode.ALWAYS)
//@EnableRedissonHttpSession
public class RedisSessionConfig {
private static final String REdis_PROTOCOL_PREFIX = "redis://";
@Value("${redis.host:127.0.0.1}")
private String host;
@Value("${redis.port:6379}")
private int port;
@Value("${redis.timeout:10000}")
private int timeout;
@Bean("springSessionDefaultRedisSerializer")
public RedisSerializer genericJackson2RedisSerializer() {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withIsGetterVisibility(com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE)
.withFieldVisibility(com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE));
mapper.configure(DeserializationFeature.FAIL_ON_UNKNowN_PROPERTIES,false);
mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES,false);
//initTypeInclusion(mapper);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.PROPERTY);
mapper.registerModules(SecurityJackson2Modules.getModules(this.getClass().getClassLoader()));
mapper.setSerializationInclusion(Include.NON_EMPTY);
TypeResolverBuilder<?> typeBuilder = mapper.getDeserializationConfig().getDefaultTyper(null);
Class clzz = typeBuilder.getDefaultImpl();
mapper.getRegisteredModuleIds();
SimpleModule simpleModule = new SimpleModule("cachemodule");
simpleModule.addDeserializer(UserData.class,new CustomDeserializer<UserData>(UserData.class));
simpleModule.addDeserializer(UserCacheData.class,new CustomDeserializer<UserCacheData>(UserCacheData.class));
simpleModule.addSerializer(UserCacheData.class,new CustomSerializer<UserCacheData>(UserCacheData.class));
mapper.registerModule(simpleModule);
return new GenericJackson2JsonRedisSerializer(mapper);
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)