分布式视频会议(Spring-Boot(六) 分布式会话管理)java基础 / Java Web应用中的分布式会话管理...

wufei123 发布于 2024-07-03 阅读(10)

### 前言 使用Spring Security的时候,觉得省了好多的事情但是它使用的是内存来存储CurrentUser的信息 和登录凭证,一旦单机不能承受大用户量,就需要水平扩展,就会涉及到session的问题。

怎么才能实现 平滑扩展呢?还好有Sping Session,怎么用呢?开发环境:OS: Mac 10.11.6IDE: IDEABuild: Maven### Spring Session 是什么 其实也不是什么新鲜的事儿?我们在实现用户登录,授权的时候,最初是web场景,我们只需要在Cookies中

分布式视频会议(Spring-Boot(六) 分布式会话管理)java基础 / Java Web应用中的分布式会话管理...

操作即可,现在我们面临移动端、open API等多种场景,单纯的Cookies已经不满足或者不能优雅的体现Restful 风格,此时需要在Header上动手脚,也就是把原来存放在Cookies中的信息移到了Header中,换汤不换药

### 在Web中使用CookieHttpSessionStrategy```java @Bean public HttpSessionStrategy httpSessionStrategy() { return new CookieHttpSessionStrategy();

}```### 在Header中使用HeaderHttpSessionStrategy```java @Bean public HttpSessionStrategy httpSessionStrategy() {

return new HeaderHttpSessionStrategy(); }```### Session 外部存储单纯的把Session信息存在JVM内容已经不适合现在的技术架构,再加上外部存储的开源产品足够成熟(Redis等),

于是Sping Session对HttpSession进行了重新包装,使其很容易结合Redis等开源产品,节省了我们的开发时间只需要在你自己实现的WebSecurityConfigurerAdapter中加上如下注解:。

```@EnableRedisHttpSession```### Cookies和Header混合支持但是在使用的过程中遇到一个问题,需要Cookie和Header都支持,这下麻烦了,还需要自己去实现,

怎么才能都支持呢?那就是在自己实现的AllHttpSessionStrategy中,对Request进行判断,如果是html,就使用CookieHttpSessionStrategy,如果是API就用HeaderHttpSessionStrategy,具体如下:

``` @Bean public HttpSessionStrategy httpSessionStrategy() { return new MyHttpSessionStrategy(new HeaderContentNegotiationStrategy());

}```这里的MyHttpSessionStrategy是要自己实现的```public class MyHttpSessionStrategy implements HttpSessionStrategy {

private HttpSessionStrategy browser; private HttpSessionStrategy api; private RequestMatcher browserMatcher;

@Autowired public MyHttpSessionStrategy(ContentNegotiationStrategy contentNegotiationStrategy) { this(new CookieHttpSessionStrategy(), new HeaderHttpSessionStrategy());

MediaTypeRequestMatcher matcher = new MediaTypeRequestMatcher(contentNegotiationStrategy, Arrays.asList(MediaType.TEXT_HTML));

matcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); RequestHeaderRequestMatcher javascript = new RequestHeaderRequestMatcher("X-Requested-With");

this.browserMatcher = new OrRequestMatcher(Arrays.asList(matcher, javascript)); } public MyHttpSessionStrategy(HttpSessionStrategy browser, HttpSessionStrategy api) {

this.browser = browser; this.api = api; } @Override public String getRequestedSessionId(HttpServletRequest request) {

return getStrategy(request).getRequestedSessionId(request); } @Override public void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response) {

getStrategy(request).onNewSession(session, request, response); } @Override public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) {

getStrategy(request).onInvalidateSession(request, response); } private HttpSessionStrategy getStrategy(HttpServletRequest request) {

return this.browserMatcher.matches(request) ? this.browser : this.api; }}```### 结束 这样无论是网页端还是RESTFull API,都可以正常支持了。

网页端通过cookie来传递session,API使用的是x-auth-token。 这里有个问题就是还不知道怎么去更新Redis中会话信息,待续...

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

河南中青旅行社综合资讯 奇遇综合资讯 盛世蓟州综合资讯 综合资讯 游戏百科综合资讯 新闻77811