个人中心项目--关于request,session,application

1.问题发现:

最近开始为项目中类似QQ聊天功能模块做准备,实现多用户在线聊天等功能就需要多个用户来访问服务器,今天突然想到,我是把登录用户信息放到session中的,那我如果多用户访问,那岂不是前一个用户的信息会被后一个用户所顶替调,毕竟都存在了session中,主要是key都是叫“user”。我还上网查了相关的问题:
在这里插入图片描述
我试了一下,在同一个浏览器打开,的确信息只能是最后登录的一个用户的信息,前一个的用户登录信息总是被后一个所顶掉。然后我就看评论中说把session的key改成动态的,然后我也试了一下,我改成了:“user”+此时登录的用户id,后台改这个部分还是很好的改的。但是前段获取这个对应的session就让我犯难了:
在这里插入图片描述
静态的session获取可以这样写,那换做动态的,这部分我该怎么写呢?技术还是有点差,我也查了一下这个问题,奈何很少有相关的资料,我之后再找找吧…继续说正题,还有一条评论这样说的,引起了我的注意:
在这里插入图片描述
他这里说的两个唯一让我很疑惑,回想起之前学servlet的域对象到现在也挺久了,好多都忘了,现在趁着遇到这部分问题,就再回去总结一下这部分内容,温故知新,系统总结一下。

首先什么是域对象,域对象是一个有作用范围的对象,可以在范围内共享数据。

2.Request:

1.什么是request和response

request和response对象是由服务器创建,提供给我们使用的。request对象是用来获取请求消息,response对象是来设置响应消息。

2.request对象继承体系

request类实现了HttpServletRequest接口,而后者由继承了ServletRequest接口。

3.request对象功能
1.获取请求消息数据
1. 获取请求行数据

先看浏览器F12里面关于访问项目路径的一些信息:
在这里插入图片描述
针对于Get方法请求的路径:http://localhost:8080/manager/profilePage?id=2
我们可以通过request中的方法获取上述对应的信息:

  • 获取请求方式 :GET
    * String getMethod()
  • 获取虚拟目录: /manager
    * String getContextPath()
  • 获取Servlet路径: /profilePage
    * String getServletPath()
  • 获取get方式请求参数:id=2
    * String getQueryString()
  • 获取请求URI:/manager/profilePage
    * String getRequestURI(): /manager/profilePage
    * StringBuffer getRequestURL() :http://localhost/manager/profilePage
    * URL:统一资源定位符 : http://localhost/manager/profilePage
    * URI:统一资源标识符 : /manager/profilePage
  • 获取客户机的IP地址:
    * String getRemoteAddr()
2. 获取请求参数
    1. String getParameter(String name):根据参数名称获取参数值 username=lc&password=123
    1. String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=sleep&hobby=game
    1. Enumeration getParameterNames():获取所有请求的参数名称
    1. Map<String,String[]> getParameterMap():获取所有参数的map集合
3. 共享数据

request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据,注意,转发时可以共享这个request,因为转发就是一次请求,而重定向是两次请求,所以是两个不同的request。
我们可以通过以下方法来实现数据共享:

    1. void setAttribute(String name,Object obj):存储数据
    1. Object getAttitude(String name):通过键获取值
    1. void removeAttribute(String name):通过键移除键值对
4.会话技术

一次会话包含多次请求与响应,我们怎么判定是一次会话呢?浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止,这就是一次会话。而我们这个项目中,当用户登陆以后,信息将被存到session中,那么在整个这次会话中,用户信息是都可以在多次请求中共享的,除非关闭浏览器或者关闭服务器。自动登陆模块用到的cookie,其实也是属于会话,只不过它是在客户端使用的会话技术,或者说浏览器,它将数据保存在客户端,而session属于服务器端的会话技术,将数据保存在服务器端的对象中。

4.1 cookie
    1. 创建Cookie对象,绑定数据
      * new Cookie(String name, String value)
    1. 发送Cookie对象
      * response.addCookie(Cookie cookie)
    1. 获取Cookie,拿到数据
      * Cookie[] request.getCookies()
    1. Cookie的特点和作用
      a. cookie存储数据在客户端浏览器
      b. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)
4.2 session
    1. 获取HttpSession对象:
      HttpSession session = request.getSession();
    1. 使用HttpSession对象:
      Object getAttribute(String name)
      void setAttribute(String name, Object value)
      void removeAttribute(String name)

注意:Session的实现是依赖于Cookie的。Session被创建后,同时还会有一个名为JSESSIONID的Cookie被创建。这个Cookie的默认时效就是当前会话。Session被创建后,对应的Cookie被保存到浏览器中,之后浏览器每次访问项目时都会携带该Cookie。当我们再次调用时会根据该JSESSIONID获取已经存在的Cookie,而不是在创建一个新的Cookie。如果Cookie中有JSESSIONID,但是JSESSIONID没有对应的Session存在,则会重新创建一个HttpSession对象,并重新设置JSESSIONID。

我们上面提到过,一次会话的结束是以客户端或者服务器端关闭而定义的。所以,当一方关闭以后,再次开启时,两次session不是同一个,这也是我们为什么当关闭浏览器后,再打开访问我们的项目时,需要重新登录,因为上一次存在session中的用户信息已经没有了,新创建的session中没有用户信息。当然,如果想要两次session是同一以session的话,我们可以通过其他方法实现,这里就不在延伸了。

那session什么时候会被销毁呢?有三种方式,第一种是关闭服务器,第二种是调用session对象的invalidate()方法来实现销毁,第三种时设置自动失效时间,默认是30分钟,即30分钟后,该session将被销毁。

  • session与Cookie的区别:
    1. session存储数据在服务器端,Cookie在客户端
    2. session没有数据大小限制,Cookie有
    3. session数据安全,Cookie相对于不安全
Session的活化和钝化
  • 当访问应用的用户很多时,服务器上就会创建非常多的Session对象,如果不对这些Session对象进行处理,那么在Session失效之前,这些Session一直都会在服务器的内存中存在。这样是对内存不太友好的,所以就出现了Session活化和钝化的机制。
  • Session钝化:Session在一段时间内没有被使用时,会将当前存在的Session对象序列化到磁盘上,而不再占用内存空间。
  • Session活化:Session被钝化后,服务器再次调用Session对象时,将Session对象由磁盘中加载到内存中使用。
  • 如果希望Session域中的对象也能够随Session钝化过程一起序列化到磁盘上,则对象的实现类也必须实现java.io.Serializable接口。不仅如此,如果对象中还包含其他对象的引用,则被关联的对象也必须支持序列化,否则会抛出异常:java.io.NotSerializableException
5.Application(ServletContext)

Web容器在启动时,它会为每个Web应用程序都创建一个对应的ServletContext对象,它代表当前Web应用——公司法人(所以它是单例的),在服务器关闭时销毁。由于一个Web应用程序中的所有Servlet都共享同一个ServletContext对象,所有的客户端在访问服务器时都共享同一个ServletContext对象,ServletContext对象一般用于在多个客户端间共享数据时使用。

回到这个项目上,我把用户信息放到session中,所以在同一个浏览器中,我先后登录两个用户,那么前一个用户信息总会被后一个信息所顶掉,而新打开另一个浏览器再登陆一个用户,则不会出现上述问题,两个用户信息会同时存在,因为这时我们创建的是两个session中,虽然key都叫“user”。但是如果我们将用户信息放在Application中,那么不管你换什么浏览器登录用户,前一个用户信息都将被后一个顶掉,毕竟服务器只有一个,所以Application只有那一个…

ps

以上便是我结合之前学习的笔记和网上一些资料总结的相关知识

相关资料:
servlet三大作用域:request,session,application.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值