‘壹’ 在JAVA WEB中,不同的客户端可以共用一个session吗为什么
不历枯可以,每一个新的浏览器连接上服务器后就是一个新的session。每一个浏览器连接到服务器后,实际上都表示各自的session,表示每一位不同的上网者都有各自的属性,所以新的肢历洞浏览器打开后无法取得其他session设置烂链的属性。
‘贰’ 如何在多台web服务器上共享session
放倒专门的session服凳掘悉务器里管理散纯session
如果是枣乎.net开发的,可以通过web.config配置到外边共同的一台session服务器上
‘叁’ 如何在多台web服务器上共享session
要解决多台web服务器共享session的问题,至少有以下三种方法:
一、将本该保存在web服务器磁盘上的session数据保存到cookie中
二、将本该保存在web服务器磁盘上的session数据保存到MySQL数据库中
三、将本该保存在web服务器磁盘上的session数据保存到内存数据库(memcache或redis)中
‘肆’ 如何实现不同应用之间session共享
实现同一Tomcat下两个WEB应用之穗族桥间通过session 共享数据。
查看tomcat 关于 HTTP Connector 中有个emptySessionPath 其解释如下:
If set to true, all paths for session cookies will be set to /. This can be useful for portlet specification implementations. If not specified, this attribute is set to false.
A side effect to setting this to true, is that if Tomcat creates a new session it will attempt to use the cookie session id if supplied by the client.
设置为true 发现没有用,在网上搜了一下方法,基本是这样的:
由于每个WEB应用程序都有一个唯一的一个ServletContext 实例对象,自己下面的所有的servlet 共享此ServletContext,利用ServletContext 中的setAttribute() 方法把Session 传递过去,然后在另外一个WEB程序中拿到session实例。
1、修改Tomcat---conf----server.xml文件
把
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="穗仿false" xmlValidation="false"猜猛></Host>
修改为:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">
<Context path="/Project_A" reloadable="false" crossContext="true"></Context>
<Context path="/Project_B" reloadable="false" crossContext="true"></Context>
</Host>
注意 crossContext 属性:
crossContext: Set to true if you want calls within this application to ServletContext.getContext() to successfully return a request dispatcher for other web applications running on this virtual host. Set to false (the default) in security conscious environments, to make getContext() always return null.
设置为true,说明你可以调用另外一个WEB应用程序,通过ServletContext.getContext() 获得ServletContext 然后再调用其getAttribute() 得到你要的对象。
2、在 Project_A 中,写入以下代码:
//以下内容用于测试同一tomcat下不同项目之间共享session
HttpSession session = req.getSession();
session.setAttribute("name", "testuser");
session.setMaxInactiveInterval(1800);
ServletContext ContextA =req.getSession().getServletContext();
ContextA.setAttribute("session", req.getSession());
//测试
out.println("IN SessionRangleServlet name : "+session.getAttribute("name"));
3、在 Project_B 中,写入以下代码取出Session
HttpSession session1 = req .getSession();
ServletContext Context = session1.getServletContext();
// 这里面传递的是 Project_A 的虚拟路径
ServletContext Context1= Context.getContext("/Project_A");
System.out.println(Context1);
HttpSession session2 =(HttpSession)Context1.getAttribute("session");
System.out.println("base传过来的user为:"+session2.getAttribute("name"));
然后重新部署。
Tomcat下配置Session Cookie位置
最近部署一个Java应用的时候要求Session Cookie位置为根目录 “/” 而不是 /context。在配置Tomcat的时候碰到了一些问题,把我的解决过程写下来,希望给碰到同样问题的朋友一些帮助。
很多时候我们要求 Session Cookie的位置在根目录“/”这样多个应用可以互相交互。Tomcat的默认设置Session Cookie是在 /context 下。
在Tomcat 6 下,修改非常简单,只要在Connector 下增加 emptySessionPath="true" 属性就能解决了。可是到了Tomcat 7 ,这个配置不起作用了。
于是查了 Servlet 3.0 spec,发现Servlet 3.0 是允许 per-context basis 配置的,那么没有理由Tomcat 7 不支持啊。
后来仔细研究了一下 Tomcat 7 的配置,原来Tomcat 7 把这个配置单独出来了,由一个sessionCookiePath属性了。
<Context ... sessionCookiePath="/" > ... </Context>
最后试验了一下,一切OK。
你来我们群里说吧
这里是开发者互相学习交流的
有大神
让他们给你解释你的疑问 q un号: 188 168040
‘伍’ 在每次访问web应用的时候都会创建一个session。怎样能实现session的单例。
Session不可能单例。如果使用单例的话就意味着整个应用程序的所有用户共享同个Session (全局)。而session主要的作用是为每个登录用户创建一个会话。这于session的作用相违背
如何lz想要保存全局的数据的话,可以使用Application对象。
‘陆’ websphere8.5.5 session共享的配置问题
需要配置,在应用服务器里面选择袭档袜部署war包的server,右侧点击会话管理-》分布式设置-》分布式会话里面选择内存到蠢拿内存拍激,就可以了
‘柒’ C# webbrowser控件 2个窗体2个webbrowser 如何共享SESSION
webBrowser2.DocumentStream = webBrowser1.DocumentStream;
webBrowser2.Document.Cookie = webBrowser1.Document.Cookie;
webBrowser2.Url = webBrowser1.Url;
这样做就神敬桐稿纯可以了,我用163邮游坦箱做了测试,可行的。
‘捌’ web集群怎么共享同步sessionWindows服务器操作系统
首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。服务器选定后,即命令它保存“tokyo”及其值。
图2 分布式简介:添加时
同样,“kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存。接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。
图3 分布式简介:获取时
这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。 memcached服务器增多后,键就会分散,即使一台memcached服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。
Php+memcache实现分布式:
‘玖’ 两个在不同机器上的tomcat,分别有两个不同的java web项目,怎么实现两个项目的session共享
单点登录,集群
‘拾’ shirocas怎么做session共享redis tomcat
第一步:配置WEB.XML
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle<磨哗/param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第二步:SHIRO整合SPRING配置
applicationContext-shiro.xml 伪代码:
<!--Session集群配置-->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="3600000"/>
<property name="sessionDAO" ref="zkShiroSessionDAO"/>
<property name="sessionValidationScheler" ref="sessionValidationScheler"/>
<property name="" value="true"/>
<property name="sessionIdCookie" ref="wapsession"/>
</bean>
<!--
指定本系统SESSIONID, 默认为: JSESSIONID
问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配搭游薯值导致登录会话丢失!
-->
<bean id="wapsession" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg name="name" value="WAPSESSIONID"/>
</bean>
<!--
定时清理僵尸session,Shiro会启用一个后台守护线程定时执行清理操作
用户直接关闭浏览器造成的孤立会话
-->
<知者bean id="sessionValidationScheler"
class="org.apache.shiro.session.mgt.">
<property name="interval" value="3600000"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
<!--由zk做session存储容器-->
<bean id="zkShiroSessionDAO" class="b2gonline.incometaxexamine._systembase.shiro.ZKShiroSessionDAO">
<!--使用内存缓存登录用户信息,一次获取用户登录信息后缓存到内存减少Shiro大量的读取操作,用户退出或超时后自动清除-->
<constructor-arg name="useMemCache" value="true"/>
<property name="zookeeperTemplate" ref="zookeeperTemplate"/>
<property name="shiroSessionZKPath" value="/SHIROSESSIONS"/>
<property name="sessionPrefix" value="session-"/>
</bean>
<!-- SHIRO安全接口 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
...
<property name="sessionManager" ref="sessionManager"/>
</bean>
第三步:Zookeeper对Shiro-SessionDao实现类
ZKShiroSessionDAO.JAVA伪代码:
import bgonline.foundation.hadoop.zk.IZookeeperTemplate;
import bgonline.foundation.hadoop.zk.ZNode;
import org.apache.shiro.cache.AbstractCacheManager;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.MapCache;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.SerializationUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* ZOOKEEPER实现SHIRO集群SESSION存储
*
* @author aliencode
* @date 13-7-10
*/
public class ZKShiroSessionDAO extends CachingSessionDAO {
public ZKShiroSessionDAO() {
}
private boolean useMemCache = false;
/**
* SESSION ZK DAO 实例
* 如果开户缓存
* 用户登录时自动缓存, 用户登录超时自动删除
* 由于shiro的cacheManager是全局的, 所以这里使用setActiveSessionsCache直接设置Cache来本地缓存, 而不使用全局zk缓存.
* 由于同一用户可能会被路由到不同服务器,所以在doReadSession方法里也做了缓存增加.
*
* @param useMemCache 是否使用内存缓存登录信息
*/
public ZKShiroSessionDAO(boolean useMemCache) {
this.useMemCache = useMemCache;
if (useMemCache) {
setActiveSessionsCache(
new MapCache<>(this.ACTIVE_SESSION_CACHE_NAME, new ConcurrentHashMap<Serializable, Session>())
);
}
}
Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* ZK操作类
*/
private IZookeeperTemplate zookeeperTemplate;
/**
* 缓存根路径, 结尾不加/
*/
private String shiroSessionZKPath = "/SHIROSESSIONS";
/**
* 缓存项前缀
*/
private String sessionPrefix = "session-";
/**
* 设置Shiro Session 前缀 默认 session-
*
* @param sessionPrefix
*/
public void setSessionPrefix(String sessionPrefix) {
this.sessionPrefix = sessionPrefix;
}
public void setZookeeperTemplate(IZookeeperTemplate zookeeperTemplate) {
this.zookeeperTemplate = zookeeperTemplate;
}
/**
* 设置Shiro在ZK服务器存放根路径
*
* @param shiroSessionZKPath 默认值:/SHIROSESSIONS/
*/
public void setShiroSessionZKPath(String shiroSessionZKPath) {
this.shiroSessionZKPath = shiroSessionZKPath;
}
/**
* session更新
*
* @param session
* @throws UnknownSessionException
*/
@Override
public void update(Session session) throws UnknownSessionException {
if (session == null || session.getId() == null) {
logger.error("session argument cannot be null.");
}
saveSession(session, "update");
}
@Override
protected void doUpdate(Session session) {
}
/**
* session删除
*
* @param session
*/
@Override
public void delete(Session session) {
if (session == null || session.getId() == null) {
logger.error("session argument cannot be null.");
}
logger.debug("delete session for id: {}", session.getId());
zookeeperTemplate.deleteNode(getPath(session.getId()));
if (useMemCache) {
this.uncache(session);
}
}
@Override
protected void doDelete(Session session) {
}
/**
* 获取当前活跃的session, 当前在线数量
*
* @return
*/
@Override
public Collection<Session> getActiveSessions() {
ZNode zNode = new ZNode();
zNode.setPath(shiroSessionZKPath);
Set<Session> sessions = new HashSet<Session>();
//读取所有SessionID , 返回形如: session-9e3b5707-fa80-4d32-a6c9-f1c3685263a5
List<String> ss = zookeeperTemplate.getChildren(zNode);
for (String id : ss) {
if (id.startsWith(sessionPrefix)) {
String noPrefixId = id.replace(sessionPrefix, "");
Session session = doReadSession(noPrefixId);
if (session != null) sessions.add(session);
}
}
logger.debug("shiro getActiveSessions. size: {}", sessions.size());
return sessions;
}
/**
* 创建session, 用户登录
*
* @param session
* @return
*/
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
saveSession(session, "create");
return sessionId;
}
/**
* session读取
*
* @param id
* @return
*/
@Override
protected Session doReadSession(Serializable id) {
if (id == null) {
logger.error("id is null!");
return null;
}
logger.debug("doReadSession for path: {}", getPath(id));
Session session;
byte[] byteData = zookeeperTemplate.getData(getPath(id)).getByteData();
if (byteData != null && byteData.length > 0) {
session = (Session) SerializationUtils.deserialize(byteData);
if (useMemCache) {
this.cache(session, id);
logger.debug("doReadSession for path: {}, add cached !", getPath(id));
}
return session;
} else {
return null;
}
}
/**
* 生成全路径
*
* @param sessID
* @return
*/
private String getPath(Serializable sessID) {
return shiroSessionZKPath + '/' + sessionPrefix + sessID.toString();
}
/**
* session读取或更新
*
* @param session
* @param act update/save
*/
private void saveSession(Session session, String act) {
Serializable sessionId = session.getId();
ZNode sessionNode = new ZNode();
sessionNode.setByteData(SerializationUtils.serialize(session));
sessionNode.setPath(getPath(sessionId));
logger.debug("save session for id: {}, act: {}", sessionId, act);
if (act == "update")
zookeeperTemplate.setData(sessionNode);
else
zookeeperTemplate.createNode(sessionNode);
}
}