想来也不少伙伴像我一样,一直在找完美的JFinal-undertow分布式session解决方案。之前有伙伴使用拦截器的方式曲线救国去实现分布式session,虽然确实也能实现,但个中滋味,只有自己知道。
经过一番研究,在@JFinal和@SuperEric的帮助下,完美解决了JFinal-undertow的分布式session问题。
首先,去github上下一个别人扩展好的一个RedisSessionManager,下载地址:
https://github.com/coat/undertow-redis-session
这上面下的,只需要使用到里面的RedisSessionManager这个一个类文件。其他的都可以不要。
我是用这个文件,然后自己又扩展了一些功能,这里就不再献丑了。
然后再创建一个RedisSessionManagerFactory类,代码如下:
import java.net.URI;
import io.undertow.server.session.SessionCookieConfig;
import io.undertow.server.session.SessionManager;
import io.undertow.servlet.api.Deployment;
import io.undertow.servlet.api.SessionManagerFactory;
public class RedisSessionManagerFactory implements SessionManagerFactory {
	private URI redisUri;
	public RedisSessionManagerFactory(URI redisUri) {
		this.redisUri = redisUri;
	}
	@Override
	public SessionManager createSessionManager(Deployment arg0) {
		SessionCookieConfig sessionConfig = new SessionCookieConfig();
        sessionConfig.setCookieName("session");
		return new RedisSessionManager(redisUri, sessionConfig);
	}
}最后在MainConfig里的main方法里这么写:
public static void main(String[] args) {
		UndertowServer.create(MainConfig.class,"undertow.properties")
		.configWeb(builder -> {
			Prop p = PropKit.use(ConstantConfig.CONFIG_FILE).appendIfExists(ConstantConfig.CONFIG_FILE_PRO);
			String deployMode = p.get("deploy.mode", ConstantConfig.DEPLOY_NORMAL);
			String sessionStorage = p.get("deploy.session.storage", "");
			boolean isDistributed = ConstantConfig.DEPLOY_DISTRIBUTED.equals(deployMode);
			//如果是分布式部署,并且session被配置到redis
			if(isDistributed && "redis".equals(sessionStorage)) {
				try {
					String redisHost = p.get("deploy.session.redis.host", "127.0.0.1");
					String redisPort = p.get("deploy.session.redis.port", "6379");
					String redisDb = p.get("deploy.session.redis.db", "0");
					String redisUri = "redis://"+redisHost+":"+redisPort+"/"+redisDb;
					builder.getDeploymentInfo().setSessionManagerFactory(new RedisSessionManagerFactory(new URI(redisUri)));
				} catch (URISyntaxException e) {
					e.printStackTrace();
				}
			}
            // 配置WebSocket需使用ServerEndpoint注解
            builder.addWebSocketEndpoint("cn.york.common.websocket.WebSocketEndpoint");
        })
		.start();
	}这里只是我这里写的方法,因为我要判断是单机部署,还是分布式部署。这里仅供参考。主要是这句代码:
builder.getDeploymentInfo().setSessionManagerFactory(new RedisSessionManagerFactory(new URI(redisUri)));
先把你的redis启动起来,然后再启动你的程序,打开浏览器,看看是不是一切都清爽了。
使用这种方法,你之前的getSessionAttr,setSessionAttr等一系列操作完全不用修改。你就当是单机一样使用就行了。
再次体现了JFinal的开发初衷:极简!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
builder.getDeploymentInfo().setSessionManagerFactory(...)
很有探索精神,收藏点赞,以后有用