单个Web应用的Session的默认超时时间,可以在应用的web.xml的session-config标签中设置,如果没有设置,那么将会以服务器的时间为准,单位是分钟,值为零或负数表示Session永不超时,如下案例:
对于单个Session对象,可以通过在代码中调用setMaxInactiveInterval方法设置超时时间,单位是秒,值为零或负数表示Session永不超时。
5 session其他常用API
================
6 SessionId的生命
==============
Session保存在服务器中,而SessionId通过Cookie发送给客户端,但我们知道Cookie的默认生命是-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。
当客户下一次打开浏览器访问的时候,虽然可能此时服务器端的Session还没有过期,但是由于没有了SessionId,那么此前的Session就找不到了,因此客户的状态可能就丢失了,可能就又需要重新登录。
对此,我们可以手动设置“JSESSIONID”的Cookie的过期时间,比如:
@WebServlet(“/session-servlet”)
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession();
Cookie jsessionid = new Cookie(“JSESSIONID”, session.getId());
jsessionid.setMaxAge(30 * 60);
jsessionid.setPath(“/”);
resp.addCookie(jsessionid);
}
}
因此,通常Cookie和Session都会结合使用!
7 URL重写
=======
如果客户端浏览器禁用了Cookie,那么浏览器就不会把Cookie带过去给服务器。对此,可以使用URL重写,将JSESSIONID直接加在请求参数后面,这样服务器可以通过获取JSESSIONID这个请求参数来得到客户端的SessionId,找到sessoin对象。
可以使用response对象调用encodeURL()或encodeRedirectURL()方法实现URL重写。在使用重定向时,需要使用encodeRedirectURL()方法。
这两个方法首先会判断当前的Servlet是否执行了HttpSession.invalidate()方法(当前session是否失效,失效后会重新建立新的session),如果已经执行返回参数URL,接下来判断客户端是否禁用了Cookie,没有禁用直接返回参数URL,如果禁用,则在URL参数中附加JSESSIONID,返回编码后的URL。
重定向的Servlet:
@WebServlet(“/url-rewrite”)
public class UrlRewrite extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
HttpSession session = req.getSession();
System.out.println("url-rewrite: "+session.getId());
//普通重定向
resp.sendRedirect(“UrlRewrite-servlet”);
//URL重写的重定向
// resp.sendRedirect(resp.encodeRedirectURL(“UrlRewrite-servlet”));
}
}
目的Servlet:
@WebServlet(“/UrlRewrite-servlet”)
public class UrlRewriteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession();
System.out.println("UrlRewrite-servlet: " + session.getId());
System.out.println();
}
}
我们尝试将浏览器的Cookie禁用(我这里是火狐浏览器):
访问“/url-rewrite”,首先使用普通重定向,控制台两个Servlet将会输出不同的Id:
接下来,我们对于UrlRewrite 使用resp.sendRedirect(resp.encodeRedirectURL(“UrlRewrite-servlet”))进行带有URL重写的重定向,结果如下:
可以发现每次重定向都使用了相同的JSESSIONID,并且我们在浏览器的请求URL参数后面可以找到携带的JSESSIONID:
如果此时在其他没有禁用Cookie的浏览器上访问, 则URL后面不会携带JSESSIONID,这就是URL重写会动态的判断客户端是否禁用了Cookie!
注意:由于附加在URL中的sessionId是动态产生的,对每一个用户是不同的,所以对于静态页面的相互跳转(比如HTML),URL重写机制无能为力。当然可以通过将静态页面转换为动态页面(比如JSP)解决。
8 Session和Cookie的区别
===================
1.从存储方式上比较
-
- Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码。
-
Session可以存储任何类型的数据,可以把Session看成是一个容器
2.从隐私安全上比较
-
- Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
-
Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。
3.从有效期上比较
-
- Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的
-
Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。
4.从对服务器的负担比较
-
- Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
-
Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪。
5.从浏览器的支持上比较
-
- 如果浏览器禁用了Cookie,那么Cookie是无用的了!
-
如果浏览器禁用了Cookie,Session可以通过URL地址重写来进行会话跟踪。
6.从跨域名上比较
-
- Cookie可以设置domain属性来实现跨域名
-
Session只在当前的域名内有效,不可夸域名
9 一次性图片验证码案例
============
生成验证码后,把验证码的数据存进Session域对象中,判断用户输入验证码是否和Session域对象的数据一致即可。并且在判断正确之后,需要防止重复提交,在实际开发过程中应该严格保证幂等性,下面的案例非常简单,仅作演示,不能在开发中使用。
图片验证码工具类:
public class ImageVerificationCode {
private int weight = 100; //验证码图片的长和宽
private int height = 30;
private String text; //用来保存验证码的文本内容
private Random r = new Random(); //获取随机数对象
//private String[] fontNames = {“宋体”, “华文楷体”, “黑体”, “微软雅黑”, “楷体_GB2312”}; //字体数组
//字体数组
private String[] fontNames = {“Georgia”};
//验证码数组
private String codes = “23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ”;
/**
-
获取随机的颜色
-
@return
*/
private Color randomColor() {
int r = this.r.nextInt(225); //这里为什么是225,因为当r,g,b都为255时,即为白色,为了好辨认,需要颜色深一点。
int g = this.r.nextInt(225);
int b = this.r.nextInt(225);
return new Color(r, g, b); //返回一个随机颜色
}
/**
-
获取随机字体
-
@return
*/
private Font randomFont() {
int index = r.nextInt(fontNames.length); //获取随机的字体
String fontName = fontNames[index];
int style = r.nextInt(4); //随机获取字体的样式,0是无样式,1是加粗,2是斜体,3是加粗加斜体
int size = r.nextInt(10) + 20; //随机获取字体的大小
return new Font(fontName, style, size); //返回一个随机的字体
}
/**
-
获取随机字符
-
@return
*/
private char randomChar() {
int index = r.nextInt(codes.length());
return codes.charAt(index);
}
/**
-
画干扰线,验证码干扰线用来防止计算机解析图片
-
@param image
*/
private void drawLine(BufferedImage image) {
int num = r.nextInt(10); //定义干扰线的数量
Graphics2D g = (Graphics2D) image.getGraphics();
for (int i = 0; i < num; i++) {
int x1 = r.nextInt(weight);
int y1 = r.nextInt(height);
int x2 = r.nextInt(weight);
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
如何快速更新自己的技术积累?
- 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
- 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
- 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
- 学习以后不知道有没有学成,则可以通过面试去检验。
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目
p1GH-1711049184866)]
如何快速更新自己的技术积累?
- 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
- 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
- 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
- 学习以后不知道有没有学成,则可以通过面试去检验。
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目
[外链图片转存中…(img-Y6pk7UZM-1711049184867)]
[外链图片转存中…(img-R7Fkn5ZH-1711049184867)]