Java Servlet中Session的原理以及使用方式,docker教程学习

单个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开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

p1GH-1711049184866)]

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

[外链图片转存中…(img-Y6pk7UZM-1711049184867)]

[外链图片转存中…(img-R7Fkn5ZH-1711049184867)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值