- 浏览: 389692 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (215)
- ubuntu (27)
- 虚拟机 (13)
- 数据库 (29)
- JAVA (40)
- 搜索 (23)
- 开发工具 (2)
- 产品 (2)
- 工具 (1)
- 应用服务器 (5)
- linux (17)
- log (1)
- 多线程 (3)
- 异常 (1)
- shell (6)
- 12306 ;互联网 (1)
- 持续集成&Hudson (4)
- js (1)
- JAVA OR-Map (1)
- 漏洞 (1)
- svn (1)
- MAVEN (3)
- 架构 (1)
- windows (1)
- json (1)
- web (3)
- jenkins (2)
- iptables (2)
- JAVA ssh (0)
- 项目管理 (1)
- tomcat (1)
- 安全 (1)
- 数据库 mysql (1)
- 性能 (1)
最新评论
-
sbwfgihc:
怎么用的啊,
<转>mysql 树查询语句 -
panghaoyu:
实现一个智能提示功能需要ajax、数据库、jsp/php、算法 ...
<转>Solr Suggest实现搜索智能提示 -
songsove:
请问您qq多少
solr 对拼音搜索和拼音首字母搜索的支持 -
panghaoyu:
实现一个智能提示功能需要ajax、数据库、jsp/php、算法 ...
<转>Solr Suggest实现搜索智能提示 -
norain1988:
这样就可以实现相关搜索了吗
solr 百度相关搜索类似功能的实现
转:http://blog.csdn.net/wmj2003/article/details/2601802
1.最近今天发现大量用户登录的时候莫名的登陆到别人的帐号,产生的原因是因为网络使用代理服务器了,在过滤器里加个网页过期时间吧,能部分解决这个问题
基本解决方法
((HttpServletResponse)response).setHeader("Pragma", "no-cache");
((HttpServletResponse)response).setHeader("Cache-Control", "no-cache");
((HttpServletResponse)response).setDateHeader("Expires", 0L);
chain.doFilter(request, response);
但是有的时候不能完全解决,还有一种可能是是session重置的时候没有清空,使用
session.clear();会大量的解决此问题
2. 另外在js中使用模态对话框的时候注意缓存问题,不然就有可能产生类似于串session的现象:
通过ShowModalDialog打开的页面会自动从IE的缓存中获得内容并显示。
如果想每次通过ShowModalDialog打开的页面都自动刷新的话,只需要在脚本
中设定一个参数,例如:
ShowModalDialog("xxx.aspx?id=1&tempid=223");
其中tempid是一个xxx.aspx中并不需要使用到的参数,只要这个参数每次不同,
通过ShowModalDialog打开的页面就都会自动刷新。
知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:
1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);
2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?
3、如何限制不同的用户在同一台机器上登陆系统?
4、管理员如何踢人?
我们首先来分析上面的问题:
首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的ID,session对象。(记住session的ID极其重要,因为服务器识别session是根据id,只要id相同,服务器就认为是同一个用户);
(上面解决了问题1)
这样当用户登陆系统的时候我们首先根据帐号判断用户是否登陆了,如果已经登陆,提示用户;(这样就解决了问题2)
如果未登陆,判断用户的session的id是否已经在用户的信息OnLineUserManager里面了,如果是提示用户
关闭当前窗口,重新点击IE打开一个新的浏览器窗口。(这样session就不会混乱了)。
如果要限制不同的用户在同一台机器上登陆系统?这个就要根据IP地址来判断了。如果OnLineUserManager中
有通过这个机器登陆系统的用户,那么就提示用户同一台机器只能够一个帐号登陆;
(问题3也就解决了,注意:如果用户使用了代理服务器,那么此方法失效。这个方法适用于管理规范的用户,客户在局域网内使用,每个客户有固定的ip。)
问题4如何踢人?你想想OnLineUserManager中记录了用户session对象,只要根据用户的帐号找到对应的
session对象,然后session.invalidate();这样就可以彻底的将捣乱的人提出系统了。
解决IE8测试时session共享问题:
1、在IE8的快捷方式的目标栏中添加-nomerge,再打开IE时就不会共享同一个session了。
2、使用命令行参数 iexplore.exe -nomerge 来打开IE。
关于浏览器的session的问题,有2种情况,IE系列,所有tab不共用一个session,除非是继承tab【通过ctrl+n打开的新窗口】;FF等所有tab共用一个session。此外服务器端判定一个请求是否是新请求,是否需要创建新session可以通过ip来决定,也就是说可以通过IP欺骗来达到每一个虚拟用户请求都会得到不同的session
===============需要注意的是OnLineUserManager必须是线程安全的=我的实现如下==============
[java] view plaincopy
package com.work.qxgl.login;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.work.util.DateUtil;
/**
* 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。
* TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制!
* 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录!
*
* @author wangmingjie
*
*/
public class OnLineUserManager {
private static Log log = LogFactory.getLog(OnLineUserManager.class);
private Vector<OnLineUser> users = null;
private OnLineUserManager() {
users = new Vector<OnLineUser>();//在构造函数中初始化
}
static class SingletonHolder {
static OnLineUserManager instance = new OnLineUserManager();
}
/**
* 单例模式。这样简单而且能够保证线程安全。
*
* @return
*/
public static OnLineUserManager getInstance() {
return SingletonHolder.instance;
}
/**
* 获取到登录用户的数量。
*
* @return
*/
public synchronized int getCount() {
users.trimToSize();
return users.capacity();
}
/**
* 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。
*
* @param userAccount
* @return
*/
public synchronized boolean existUser(String userAccount) {
users.trimToSize();
boolean existUser = false;
for (int i = 0; i < users.capacity(); i++) {
if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
existUser = true;
break;
}
}
return existUser;
}
/**
* @param sessionid
* @return
*/
public synchronized boolean existSession(String sessionid) {
users.trimToSize();
boolean existUser = false;
for (int i = 0; i < users.capacity(); i++) {
if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {
existUser = true;
break;
}
}
return existUser;
}
/**
* 删除用户
*
* @param userAccount
* @return
*/
public synchronized boolean deleteUser(String userAccount) {
users.trimToSize();
if (existUser(userAccount)) {
int currUserIndex = -1;
for (int i = 0; i < users.capacity(); i++) {
if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
currUserIndex = i;
break;
}
}
if (currUserIndex != -1) {
users.remove(currUserIndex);
users.trimToSize();
log.debug("用户" + userAccount + "退出系统"
+ DateUtil.getCurrentDateTime());
log.debug("在线用户数为:" + getCount());
return true;
}
}
return false;
}
/**
* 根据用户帐号,获取在线用户信息
* @param userAccount
* @return
*/
public synchronized OnLineUser getUser(String userAccount) {
users.trimToSize();
if (existUser(userAccount)) {
int currUserIndex = -1;
for (int i = 0; i < users.capacity(); i++) {
if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
currUserIndex = i;
break;
}
}
if (currUserIndex != -1) {
return users.get(currUserIndex);
}
}
return null;
}
/**
* 获取到在线用户的信息。
*
* @return
*/
public synchronized Vector<OnLineUser> getOnLineUser() {
return users;
}
public synchronized void addUser(OnLineUser onLineUser) {
users.trimToSize();
if (!existUser(onLineUser.getUserAccount())) {
users.add(onLineUser);
log.debug(onLineUser.getUserAccount() + "/t登录到系统/t" + DateUtil.getCurrentDateTime());
// 通过request才能够获取到用户的ip等信息
} else {
log.debug(onLineUser.getUserAccount() + "已经存在");
}
log.debug("在线用户数为:" + getCount());
}
}
==================OnLineUser.java============================
[java] view plaincopy
package com.work.qxgl.login;
import java.io.Serializable;
import javax.servlet.http.HttpSession;
/**
* @author wangmingjie
* @date 2008-6-30下午04:56:37
*/
public class OnLineUser implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5461473880667036331L;
private String userId; //用户id
private String userAccount; //用户帐号
private String userName; //用户名称
private String loginTime; //登陆时间戳
private String sessionId; //session的ID
private String userIp ;//ip地址
private HttpSession session; //记住session对象,测试能否用来将人员踢出系统
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getUserIp() {
return userIp;
}
public void setUserIp(String userIp) {
this.userIp = userIp;
}
public HttpSession getSession() {
return session;
}
public void setSession(HttpSession session) {
this.session = session;
}
public String getLoginTime() {
return loginTime;
}
public void setLoginTime(String loginTime) {
this.loginTime = loginTime;
}
public String toString(){
return "OnLineUser{userId="+userId+",userAccount="+userAccount
+",userName"+userName+",loginTime="+loginTime+",userIp="+userIp+",sessionId="+sessionId+"}";
}
//===============下面的数据只有在系统登陆日期中记录==================================
// private String logoutTime;//退出时间戳;
// private String logoutType;//退出方式 “session超时退出”;“1主动退出”
// private String lastAccessedTime;// 最后访问时间
}
控制一个用户多次登录,当session有效时,如果相同用户登录,就提示已经登录了,当session失效后,就可以不用提示,直接登录了。
那么如何在session失效后,进行一系列的操作呢?
这里就需要用到监听器了,即当session因为各种原因失效后,监听器就可以监听到,然后执行监听器中定义好的程序就可以了。
监听器类为:HttpSessionListener类,有sessionCreated和sessionDestroyed两个方法
自己可以继承这个类,然后分别实现。
sessionCreated指在session创建时执行的方法
sessionDestroyed指在session失效时执行的方法
给一个简单的例子:
public class SessionListener implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent event) {
HttpSession ses = event.getSession();
String id=ses.getId()+ses.getCreationTime();
SummerConstant.UserMap.put(id, Boolean.TRUE); //添加用户
}
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession ses = event.getSession();
String id=ses.getId()+ses.getCreationTime();
synchronized (this) {
SummerConstant.USERNUM--; //用户数减一
SummerConstant.UserMap.remove(id); //从用户组中移除掉,用户组为一个map
}
}
}
然后只需要把这个监听器在web.xml中声明就可以了
<listener>
<listener-class>
com.demo.SessionListener
</listener-class>
</listener>
1.最近今天发现大量用户登录的时候莫名的登陆到别人的帐号,产生的原因是因为网络使用代理服务器了,在过滤器里加个网页过期时间吧,能部分解决这个问题
基本解决方法
((HttpServletResponse)response).setHeader("Pragma", "no-cache");
((HttpServletResponse)response).setHeader("Cache-Control", "no-cache");
((HttpServletResponse)response).setDateHeader("Expires", 0L);
chain.doFilter(request, response);
但是有的时候不能完全解决,还有一种可能是是session重置的时候没有清空,使用
session.clear();会大量的解决此问题
2. 另外在js中使用模态对话框的时候注意缓存问题,不然就有可能产生类似于串session的现象:
通过ShowModalDialog打开的页面会自动从IE的缓存中获得内容并显示。
如果想每次通过ShowModalDialog打开的页面都自动刷新的话,只需要在脚本
中设定一个参数,例如:
ShowModalDialog("xxx.aspx?id=1&tempid=223");
其中tempid是一个xxx.aspx中并不需要使用到的参数,只要这个参数每次不同,
通过ShowModalDialog打开的页面就都会自动刷新。
知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:
1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);
2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?
3、如何限制不同的用户在同一台机器上登陆系统?
4、管理员如何踢人?
我们首先来分析上面的问题:
首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的ID,session对象。(记住session的ID极其重要,因为服务器识别session是根据id,只要id相同,服务器就认为是同一个用户);
(上面解决了问题1)
这样当用户登陆系统的时候我们首先根据帐号判断用户是否登陆了,如果已经登陆,提示用户;(这样就解决了问题2)
如果未登陆,判断用户的session的id是否已经在用户的信息OnLineUserManager里面了,如果是提示用户
关闭当前窗口,重新点击IE打开一个新的浏览器窗口。(这样session就不会混乱了)。
如果要限制不同的用户在同一台机器上登陆系统?这个就要根据IP地址来判断了。如果OnLineUserManager中
有通过这个机器登陆系统的用户,那么就提示用户同一台机器只能够一个帐号登陆;
(问题3也就解决了,注意:如果用户使用了代理服务器,那么此方法失效。这个方法适用于管理规范的用户,客户在局域网内使用,每个客户有固定的ip。)
问题4如何踢人?你想想OnLineUserManager中记录了用户session对象,只要根据用户的帐号找到对应的
session对象,然后session.invalidate();这样就可以彻底的将捣乱的人提出系统了。
解决IE8测试时session共享问题:
1、在IE8的快捷方式的目标栏中添加-nomerge,再打开IE时就不会共享同一个session了。
2、使用命令行参数 iexplore.exe -nomerge 来打开IE。
关于浏览器的session的问题,有2种情况,IE系列,所有tab不共用一个session,除非是继承tab【通过ctrl+n打开的新窗口】;FF等所有tab共用一个session。此外服务器端判定一个请求是否是新请求,是否需要创建新session可以通过ip来决定,也就是说可以通过IP欺骗来达到每一个虚拟用户请求都会得到不同的session
===============需要注意的是OnLineUserManager必须是线程安全的=我的实现如下==============
[java] view plaincopy
package com.work.qxgl.login;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.work.util.DateUtil;
/**
* 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。
* TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制!
* 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录!
*
* @author wangmingjie
*
*/
public class OnLineUserManager {
private static Log log = LogFactory.getLog(OnLineUserManager.class);
private Vector<OnLineUser> users = null;
private OnLineUserManager() {
users = new Vector<OnLineUser>();//在构造函数中初始化
}
static class SingletonHolder {
static OnLineUserManager instance = new OnLineUserManager();
}
/**
* 单例模式。这样简单而且能够保证线程安全。
*
* @return
*/
public static OnLineUserManager getInstance() {
return SingletonHolder.instance;
}
/**
* 获取到登录用户的数量。
*
* @return
*/
public synchronized int getCount() {
users.trimToSize();
return users.capacity();
}
/**
* 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。
*
* @param userAccount
* @return
*/
public synchronized boolean existUser(String userAccount) {
users.trimToSize();
boolean existUser = false;
for (int i = 0; i < users.capacity(); i++) {
if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
existUser = true;
break;
}
}
return existUser;
}
/**
* @param sessionid
* @return
*/
public synchronized boolean existSession(String sessionid) {
users.trimToSize();
boolean existUser = false;
for (int i = 0; i < users.capacity(); i++) {
if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {
existUser = true;
break;
}
}
return existUser;
}
/**
* 删除用户
*
* @param userAccount
* @return
*/
public synchronized boolean deleteUser(String userAccount) {
users.trimToSize();
if (existUser(userAccount)) {
int currUserIndex = -1;
for (int i = 0; i < users.capacity(); i++) {
if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
currUserIndex = i;
break;
}
}
if (currUserIndex != -1) {
users.remove(currUserIndex);
users.trimToSize();
log.debug("用户" + userAccount + "退出系统"
+ DateUtil.getCurrentDateTime());
log.debug("在线用户数为:" + getCount());
return true;
}
}
return false;
}
/**
* 根据用户帐号,获取在线用户信息
* @param userAccount
* @return
*/
public synchronized OnLineUser getUser(String userAccount) {
users.trimToSize();
if (existUser(userAccount)) {
int currUserIndex = -1;
for (int i = 0; i < users.capacity(); i++) {
if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
currUserIndex = i;
break;
}
}
if (currUserIndex != -1) {
return users.get(currUserIndex);
}
}
return null;
}
/**
* 获取到在线用户的信息。
*
* @return
*/
public synchronized Vector<OnLineUser> getOnLineUser() {
return users;
}
public synchronized void addUser(OnLineUser onLineUser) {
users.trimToSize();
if (!existUser(onLineUser.getUserAccount())) {
users.add(onLineUser);
log.debug(onLineUser.getUserAccount() + "/t登录到系统/t" + DateUtil.getCurrentDateTime());
// 通过request才能够获取到用户的ip等信息
} else {
log.debug(onLineUser.getUserAccount() + "已经存在");
}
log.debug("在线用户数为:" + getCount());
}
}
==================OnLineUser.java============================
[java] view plaincopy
package com.work.qxgl.login;
import java.io.Serializable;
import javax.servlet.http.HttpSession;
/**
* @author wangmingjie
* @date 2008-6-30下午04:56:37
*/
public class OnLineUser implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5461473880667036331L;
private String userId; //用户id
private String userAccount; //用户帐号
private String userName; //用户名称
private String loginTime; //登陆时间戳
private String sessionId; //session的ID
private String userIp ;//ip地址
private HttpSession session; //记住session对象,测试能否用来将人员踢出系统
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getUserIp() {
return userIp;
}
public void setUserIp(String userIp) {
this.userIp = userIp;
}
public HttpSession getSession() {
return session;
}
public void setSession(HttpSession session) {
this.session = session;
}
public String getLoginTime() {
return loginTime;
}
public void setLoginTime(String loginTime) {
this.loginTime = loginTime;
}
public String toString(){
return "OnLineUser{userId="+userId+",userAccount="+userAccount
+",userName"+userName+",loginTime="+loginTime+",userIp="+userIp+",sessionId="+sessionId+"}";
}
//===============下面的数据只有在系统登陆日期中记录==================================
// private String logoutTime;//退出时间戳;
// private String logoutType;//退出方式 “session超时退出”;“1主动退出”
// private String lastAccessedTime;// 最后访问时间
}
控制一个用户多次登录,当session有效时,如果相同用户登录,就提示已经登录了,当session失效后,就可以不用提示,直接登录了。
那么如何在session失效后,进行一系列的操作呢?
这里就需要用到监听器了,即当session因为各种原因失效后,监听器就可以监听到,然后执行监听器中定义好的程序就可以了。
监听器类为:HttpSessionListener类,有sessionCreated和sessionDestroyed两个方法
自己可以继承这个类,然后分别实现。
sessionCreated指在session创建时执行的方法
sessionDestroyed指在session失效时执行的方法
给一个简单的例子:
public class SessionListener implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent event) {
HttpSession ses = event.getSession();
String id=ses.getId()+ses.getCreationTime();
SummerConstant.UserMap.put(id, Boolean.TRUE); //添加用户
}
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession ses = event.getSession();
String id=ses.getId()+ses.getCreationTime();
synchronized (this) {
SummerConstant.USERNUM--; //用户数减一
SummerConstant.UserMap.remove(id); //从用户组中移除掉,用户组为一个map
}
}
}
然后只需要把这个监听器在web.xml中声明就可以了
<listener>
<listener-class>
com.demo.SessionListener
</listener-class>
</listener>
发表评论
-
<转>Hessian入门(与Spring集成)
2015-01-20 10:31 4432原链接:http://blog.csdn.net/chenwe ... -
<转>如何编程实现 2 + 2 = 5?
2014-10-16 11:00 828原链接:http://codeway.co/%E5%A6%82 ... -
<转>利用位操作来进行状态操作
2014-07-15 11:00 709print?<SPAN style="BACK ... -
java命令
2014-04-23 17:17 822jps -v 查看所有的jvm进程,包括进程ID,进程启动的路 ... -
<转>给Tomcat,Apache配置gzip压缩(HTTP压缩)功能
2014-03-28 14:14 452原链接:http://www.blogjava.net/juh ... -
<转>JVM调优总结 -Xms -Xmx -Xmn -Xss
2014-01-21 21:21 881原链接:http://unixboy.iteye.com/bl ... -
<转>Eclipse 常用设置
2013-12-23 16:26 714原链:http://blog.csdn.net/appleca ... -
tomcat各版本信息
2013-12-23 10:02 838Apache官方对各版本的解释:http://tomcat ... -
<转> 如何获取用户的真实IP
2013-12-23 09:40 698问题引出: 在JSP里,获取客户端的IP地址的方法是:re ... -
从SVN导出指定版本号之间修改的文件
2013-12-20 16:55 559转:http://www.kuqin.com/manageto ... -
用JAVA调用ssh命令
2013-12-09 15:21 1945原链:http://blog.csdn.net/f ... -
java执行shell命令 outputStream缓冲区阻塞
2013-11-27 15:49 1734http://bbs.csdn.net/topics/1101 ... -
java有效的IP正则表达式
2013-11-06 20:46 865public static boolean isboolIp ... -
<转>JSCH 如何实现在远程机器上执行linux命令
2013-08-23 09:34 1419原链:http://blog.csdn.net/hongbin ... -
Java JSON技术框架选型与实例
2013-08-05 15:12 804JSON JSON英文全称为JavaScript Obje ... -
JVM内存结构系列:HotSpot内存结构最清晰
2013-07-29 11:37 807SUN的jvm内存池被划分为以下几个部分:Eden Spa ... -
<转>探究两大Java内存溢出类型
2013-07-29 10:31 761你知道如何解决Java内 ... -
<转>list,set,map,数组间的相互转换
2013-07-25 12:30 990原链:http://teamojiao.iteye.com/ ... -
Eclipse调试Bug的七种常用技巧
2013-07-04 10:24 828记得刚刚毕业的时候,自己连断点也不会打,当时还在用JCre ... -
Log4j 日志级别
2013-04-19 11:10 1078级别顺序(低到高): DEBUG < INFO < ...
相关推荐
<groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.4.2</version> </dependency> ``` 然后,在`application.yml`中配置Redis连接信息以及Spring-...
"浏览器多窗口共用session引发的混乱"这个标题揭示了一个常见但往往被忽视的问题,即当用户在同一浏览器的不同窗口或标签页中打开同一个网站时,它们可能会共享同一份Session数据,这可能导致意料之外的行为和用户...
风格管理中新增操作结果混乱的问题</p><p>40、修复 IE6、IE7等浏览器提示common.js报错的Bug</p><p>41、修复 前台充值卡密页面不显示验证码和同一卡密充值2次成功的Bug</p><p>42、【轻量级 PR】:修复门户”模块...
%>`)用于定义变量或方法;脚本片段(`<% ... %>`)用于执行Java代码;表达式(`<%= ... %>`)用于将Java表达式的结果输出到HTML。 ### 7. EL和JSTL **EL (Expression Language)** 是一个轻量级的表达式语言,...
- `<scriptlet>`: `<% %>` 用于插入一段Java代码,通常用于定义方法或变量。 - `<declaration>`: `<%! %>` 用于声明变量或方法,相当于在页面级别定义变量。 - `<expression>`: 等同于JSP表达式,但在块级上下文...
public static final ThreadLocal<Session> session = new ThreadLocal<Session>() { @Override protected Session initialValue() { return sessionFactory.openSession(); } }; public static Session ...
1. **非线程安全**:由于`Session`不是线程安全的,因此在多线程环境中,每个线程都应有自己的`Session`实例,以避免数据存取的混乱。 2. **轻量级**:`Session`的创建和销毁相对快速,降低了资源的消耗。 3. **第一...
<title>你的页面标题</title> </head> <body> <!-- JSP动态内容 --> <%-- JSP注释 --%> <jsp:include page="header.jsp"/> <jsp:useBean id="myBean" class="com.example.MyBean"/> <%= "Hello, World!" %> <!...
`<scriptlet>`用于编写Java代码块, `<declaration>`声明变量或方法,`<expression>`则用于输出Java表达式的值。 5. **JSP动作标签**:如`<jsp:include>`, `<jsp:forward>`, `<jsp:param>`等,它们用于控制流程,...
- **动作(Actions)**:如`<jsp:include>`, `<jsp:forward>`, `<jsp:useBean>`等,它们用于执行服务器端的操作,比如包含其他资源或处理对象。 3. **JSP生命周期** JSP经过编译、实例化、初始化、服务和销毁五个...
- 被包含的页面不应该有`<html>`、`<head>` 或者`<body>` 这样的HTML结构元素,否则可能导致页面结构混乱。 - 包含的页面可以访问包含它的页面的所有局部变量,但不能访问其作用域内的session或application变量。 ...
2. **脚本元素**:包括`<scriptlet>`, `<expression>`, `<declaration>`,它们分别用于编写Java代码,输出表达式结果,以及声明变量或方法。 3. **动作元素**:如`<jsp:include>`, `<jsp:forward>`, `<jsp:params>`,...
### ASP.NET应用下基于SessionState的状态编程框架解决方案 #### 一、单纯基于SessionState编程的局限性 在ASP.NET开发中,SessionState是一项常用的技术,用于保存与客户端相关的状态信息。然而,仅依赖Session...
ArrayList<String> temp = (ArrayList<String>) session.getAttribute(keyword); // 使用keyword作为标识符,避免不同搜索结果之间的混淆。 ``` 3. **其他建议**: - 考虑使用更轻量级的数据结构来存储搜索结果...
Session 的概念非常混乱,有时候我们可以看到这样的话“在一个浏览器会话期间,...”,这里的会话是指从一个浏览器窗口打开到关闭这个期间;也可以看到“用户(客户端)在一次会话期间”这样一句话,它可能指用户的...
当上述方法不适用或不够理想时,Nginx提供了两种策略来解决session共享: 1. IP Hash:Nginx的ip_hash技术可以根据客户端IP地址的哈希值将请求路由到特定的后端服务器,从而确保来自同一IP的请求总是被发送到同一台...
4. **表单控件增强**:新增了更多类型的输入字段,如<date>、<range>、<email>等,增强了表单验证功能。 5. **图形绘制**:Canvas元素提供JavaScript绘图能力,SVG则支持矢量图形,两者可实现动态和交互式的视觉...
<p>两数之和是:<%= num1 + num2 %></p> </body> </html> ``` 这个例子展示了JSP的基本结构,包括`<%@ %>` 指令、表达式 `<%= %>` 和脚本元素 `<%! %>`。 在深入学习JSP时,你可能还会接触到EL(Expression ...
- **指令元素**:如`<%@ page %>`, `<%@ include %>`, `<%@ taglib %>`, 它们提供了关于整个页面或特定部分的元信息。 - **脚本元素**:包括`<scriptlet>`, `<expression>`, `<declaration>`,它们用于编写Java...