问题描述
SpringBoot项目中集成spring-session-jdbc后,
配置拦截器,拦截http请求,检查是否存在session值, 如果session不为null,返回true,继续当前http请求; 如果session为null,返回false,并且返回500
但是现在有一个场景会出现session为null的情况, 浏览器从入口url进来的时候会创建一次新的会话,并且在session里面写入值 但是当浏览器刷新过快或者请求次数过多的时候,会出现session为null的情况 求指点怎么解决这个bug,为什么会出现这个bug?**
代码
创建session
这部分代码是浏览器通过第一个接口去创建appid,并且通过spring-session-jdbc创建了一个session
@RequestMapping(value = "/init", method = RequestMethod.POST)
public ResponseEntity<ApplicationIdResponse> createApplicationId(String source, HttpServletRequest request) {
LOGGER.info("create appid started...");
ApplicationIdResponse response = personalInfoService.createApplicationId(sourceChannel);
// Params:create – true to create a new session for this request if necessary; false to return null if there's no current session
HttpSession checkSession = request.getSession(false);
log.info("[session] checkSession result: {}", checkSession);
if (checkSession != null) {
checkSession.invalidate();
//request.changeSessionId();
log.info("[session] invalidate and changeSessionId: {}", checkSession);
}
HttpSession session = request.getSession(true);
session.setAttribute("refer_id", response.getApplicationId());
return new ResponseEntity<>(response, HttpStatus.OK);
}
配置拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Resource
BeanFactory beanFactory;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new PreRequestIntercept()).addPathPatterns(
"/getInfo",
);
}
}
实现拦截器
这里只是单一的去检查session是不是null,并不做其他业务逻辑处理
当请求/init接口生成session后,在浏览器中不断刷新请求/getInfo接口的时候,偶尔会出现session为null 这个地方求指点,如何解决?
只有一个实例,不存在负载均衡问题
public class PreRequestIntercept extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
try {
HttpSession session = request.getSession(false);
log.info("[intercept check session: {}]", session);
if (session != null) {
log.info("[intercept check session is not null: {}]", session);
return true;
} else {
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
log.info("[intercept check session is null and return 500: {}]", session);
return false;
}
} catch(Exception e) {
log.info("[intercept check error: {}]", e);
return false;
}
}
}
yml文件配置
spring:
session:
store-type: jdbc
time-out: 7200
jdbc:
initialize-schema: always
cleanup-cron: 0 * * * * *
datasource:
minPoolSize: 100
maxPoolSize: 100
maxWaitTime: 30000
url: jdbc:test-db
username: test
password: test
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver