阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

会话跟踪技术-session

94次阅读
没有评论

共计 5641 个字符,预计需要花费 15 分钟才能阅读完成。

1、HttpSesssion 是什么

javax.servlet.http.HttpSession 接口表示一个会话,我们可以把一个会话内需要共享的数据保存到 HttSession 对象中!

2、获取 HttpSession 对象

HttpSession request.getSesssion():如果当前会话已经有了 session 对象那么直接返回,如果当前会话还不存在会话,那么创建 session 并返回;

HttpSession request.getSession(boolean):当参数为 true 时,与 requeset.getSession() 相同。如果参数为 false,那么如果当前会话中存在 session 则返回,不存在返回 null;

3、HttpSession 是域对象

我们已经学习过 HttpServletRequest、ServletContext,它们都是域对象,现在我们又学习了一个 HttpSession,它也是域对象。它们三个是 Servlet 中可以使用的域对象,而 JSP 中可以多使用一个域对象,明天我们再讲解 JSP 的第四个域对象。

HttpServletRequest:一个请求创建一个 request 对象,所以在同一个请求中可以共享 request,例如一个请求从 AServlet 转发到 BServlet,那么 AServlet 和 BServlet 可以共享 request 域中的数据;

ServletContext:一个应用只创建一个 ServletContext 对象,所以在 ServletContext 中的数据可以在整个应用中共享,只要不启动服务器,那么 ServletContext 中的数据就可以共享;

HttpSession:一个会话创建一个 HttpSession 对象,同一会话中的多个请求中可以共享 session 中的数据;

下载是 session 的域方法:

void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:session.setAttribute(“xxx”,“XXX”),在 session 中保存了一个域属性,域属性名称为 xxx,域属性的值为 XXX。请注意,如果多次调用该方法,并且使用相同的 name,那么会覆盖上一次的值,这一特性与 Map 相同;

Object getAttribute(String name):用来获取 session 中的数据,当前在获取之前需要先去存储才行,例如:String value = (String) session.getAttribute(“xxx”);,获取名为 xxx 的域属性;

void removeAttribute(String name):用来移除 HttpSession 中的域属性,如果参数 name 指定的域属性不存在,那么本方法什么都不做;

Enumeration getAttributeNames():获取所有域属性的名称;

4、登录案例

需要的页面:

login.jsp:登录页面,提供登录表单;

index1.jsp:主页,显示当前用户名称,如果没有登录,显示您还没登录;

index2.jsp:主页,显示当前用户名称,如果没有登录,显示您还没登录;

Servlet:

LoginServlet:在 login.jsp 页面提交表单时,请求本 Servlet。在本 Servlet 中获取用户名、密码进行校验,如果用户名、密码错误,显示“用户名或密码错误”,如果正确保存用户名 session 中,然后重定向到 index1.jsp;

当用户没有登录时访问 index1.jsp 或 index2.jsp,显示“您还没有登录”。如果用户在 login.jsp 登录成功后到达 index1.jsp 页面会显示当前用户名,而且不用再次登录去访问 index2.jsp 也会显示用户名。因为多次请求在一个会话范围,index1.jsp 和 index2.jsp 都会到 session 中获取用户名,session 对象在一个会话中是相同的,所以都可以获取到用户名!

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>login.jsp</title> </head> <body> <h1>login.jsp</h1> <hr/> <form action="/day06_4/LoginServlet" method="post"> 用户名:<input type="text" name="username" /><br/> <input type="submit" value="Submit"/> </form> </body> </html>

index1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>index1.jsp</title> </head> <body> <h1>index1.jsp</h1> <% String username = (String)session.getAttribute("username"); if(username == null) {out.print("您还没有登录!"); } else {out.print("用户名:" + username); } %> <hr/> <a href="/day06_4/index2.jsp">index2</a> </body> </html>

index2.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>index2.jsp</title> </head> <body> <h1>index2.jsp</h1> <% String username = (String)session.getAttribute("username"); if(username == null) {out.print("您还没有登录!"); } else {out.print("用户名:" + username); } %> <hr/> <a href="/day06_4/index1.jsp">index1</a> </body> </html>

LoginServlet

public class LoginServlet extends HttpServlet {public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String username = request.getParameter("username"); if(username.equalsIgnoreCase("itcast") ) {response.getWriter().print("用户名或密码错误!"); } else {HttpSession session = request.getSession(); session.setAttribute("username", username); response.sendRedirect("/day06_4/index1.jsp"); } } }

5、session 的实现原理

session 底层是依赖 Cookie 的!我们来理解一下 session 的原理吧!

当我首次去银行时,因为还没有账号,所以需要开一个账号,我获得的是银行卡,而银行这边的数据库中留下了我的账号,我的钱是保存在银行的账号中,而我带走的是我的卡号。

当我再次去银行时,只需要带上我的卡,而无需再次开一个账号了。只要带上我的卡,那么我在银行操作的一定是我的账号!

当首次使用 session 时,服务器端要创建 session,session 是保存在服务器端,而给客户端的 session 的 id(一个 cookie 中保存了 sessionId)。客户端带走的是 sessionId,而数据是保存在 session 中。

当客户端再次访问服务器时,在请求中会带上 sessionId,而服务器会通过 sessionId 找到对应的 session,而无需再创建新的 session。

会话跟踪技术 -session

6、session 与浏览器

session 保存在服务器,而 sessionId 通过 Cookie 发送给客户端,但这个 Cookie 的生命不 -1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个 Cookie 就丢失了。

当用户再次打开浏览器访问服务器时,就不会有 sessionId 发送给服务器,那么服务器会认为你没有 session,所以服务器会创建一个 session,并在响应中把 sessionId 中到 Cookie 中发送给客户端。

你可能会说,那原来的 session 对象会怎样?当一个 session 长时间没人使用的话,服务器会把 session 删除了!这个时长在 Tomcat 中配置是 30 分钟,可以在 ${CATALANA}/conf/web.xml 找到这个配置,当然你也可以在自己的 web.xml 中覆盖这个配置!

web.xml

<session-config> <session-timeout>30</session-timeout> </session-config>

session 失效时间也说明一个问题!如果你打开网站的一个页面开始长时间不动,超出了 30 分钟后,再去点击链接或提交表单时你会发现,你的 session 已经丢失了!

7、session 其他常用 API

String getId():获取 sessionId;

int getMaxInactiveInterval():获取 session 可以的最大不活动时间(秒),默认为 30 分钟。当 session 在 30 分钟内没有使用,那么 Tomcat 会在 session 池中移除这个 session;

void setMaxInactiveInterval(int interval):设置 session 允许的最大不活动时间(秒),如果设置为 1 秒,那么只要 session 在 1 秒内不被使用,那么 session 就会被移除;

long getCreationTime():返回 session 的创建时间,返回值为当前时间的毫秒值;

long getLastAccessedTime():返回 session 的最后活动时间,返回值为当前时间的毫秒值;

void invalidate():让 session 失效!调用这个方法会被 session 失效,当 session 失效后,客户端再次请求,服务器会给客户端创建一个新的 session,并在响应中给客户端新 session 的 sessionId;

boolean isNew():查看 session 是否为新。当客户端第一次请求时,服务器为客户端创建 session,但这时服务器还没有响应客户端,也就是还没有把 sessionId 响应给客户端时,这时 session 的状态为新。

8、URL 重写

我们知道 session 依赖 Cookie,那么 session 为什么依赖 Cookie 呢?因为服务器需要在每次请求中获取 sessionId,然后找到客户端的 session 对象。那么如果客户端浏览器关闭了 Cookie 呢?那么 session 是不是就会不存在了呢?

其实还有一种方法让服务器收到的每个请求中都带有 sessioinId,那就是 URL 重写!在每个页面中的每个链接和表单中都添加名为 jSessionId 的参数,值为当前 sessionid。当用户点击链接或提交表单时也服务器可以通过获取 jSessionId 这个参数来得到客户端的 sessionId,找到 sessoin 对象。

index.jsp

 <body>
<h1>URL 重写 </h1>
<a href='https://www.zutuanxue.com/day06_5/index.jsp;jsessionid=<%=session.getId() %>'  > 主页 </a>

<form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post">
	<input type="submit" value="提交"/>
</form>
  </body>

也可以使用 response.encodeURL() 对每个请求的 URL 处理,这个方法会自动追加 jsessionid 参数,与上面我们手动添加是一样的效果。

<a href='<%=response.encodeURL("/day06_5/index.jsp") %>' > 主页 </a> <form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post"> <input type="submit" value="提交"/> </form>

使用 response.encodeURL() 更加“智能”,它会判断客户端浏览器是否禁用了 Cookie,如果禁用了,那么这个方法在 URL 后面追加 jsessionid,否则不会追加。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-06-06发表,共计5641字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中