JAVAWEB——(servlet-6)

会话跟踪

1.为什么需要会话跟踪?

      使用浏览器发送的http请求http请求使用的是http协议,而http协议是一种无状态的协议,它不会去主动记录使用这个http协议的用户是谁,一旦请求发送成功,服务器做出响应以后,那么此时浏览器与服务器之间的链接就会消失,这时服务器就不知道请求来自哪里,是谁发送来的。所以这时我们就需要记录/保存请求/链接的状态,实现这个记录记录/保存请求/链接的状态的过程就叫会话跟踪

2.什么是会话跟踪?

   服务器处理程序实现记录/保存请求/链接的状态的过程就叫会话跟踪

3.四种会话跟踪技术有那些,它们各自的优缺点?

    1.URL重写:将该用户Session的id信息重写到URL地址中,以便在服务器端进行识别不同的用户。

                        https://blog.csdn.net/weixin_52192654?spm=1011.2124.3001.5343

                       URL重写能够在客户端停用cookies或者不支持cookies的时候仍然能够发挥作用

     2.隐藏表单域:将用户Session的id信息添加到HTML表单元素<input type="hidden" name="" value=""/>中提交到服务器,此表单元素并不在客户端显示,浏览时看不到,源代码中有。

     3.Cookie:Cookie是Web服务器发送给客户端的一小段信息,客户端请求时可以读取该信息发送到服务器端,进而进行用户的识别。服务器创建保存于浏览器端,不可跨域名性,大小及数量有限客户端可以采用两种方式来保存这个Cookie对象,一种方式是 保存在 客户端内存中,称为临时Cookie,浏览器关闭后 这个Cookie对象将消失。另外一种方式是保存在客户机的磁盘上,称为永久Cookie。以后客户端只要访问该网站,就会将这个Cookie再次发送到服务器上,前提是 这个Cookie在有效期内。 这样就实现了对客户的跟踪。Cookie是可以被禁止的。

      4.Session:每一个用户都有一个不同的session,各个用户之间是不能共享的,是每个用户所独享的,在session中可以存放信息。保存在服务器端。需要解决多台服务器间共享问题。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。

      Session是依赖Cookie的,如果Cookie被禁用,那么session也将失效。

     当用户第一次发送http请求到服务器,服务器端会创建一个session对象,产生一个sessionID来标识这个session对象,然后将这个sessionID放入到Cookie中发送到客户端,下一次发送http请求到服务器时,http请求会连同第一次得到的sessionID会发送到服务器,在服务器端进行识别不同的用户。

 

  上面的会话跟踪的过程与我们去超市的时候,在超市门口的储物柜中保存物品的过程相似。

4.Session和Cookie区别?

Cookie

Session

数据服务器创建保存于浏览器端

数据放在服务器上

cookie不是很安全

Session很安全

减轻服务器性能应当使用cookie。

不考虑减轻服务器性能。可以使用Session

单个cookie保存的数据不能超过4K

没有限制

 

Session是依赖Cookie的,如果Cookie被禁用,那么session也将失效。

5.HttpSession的常用方法

   Servlet中的HttpSession接口

  1. 通过HttpServletRequest对象的getSession()方法得到HttpSession接口对象
  2. HttpSession接口对象常用方法

方法声明

功能描述

String  getId()

该方法用于得到sessionID

long  getCreationTime()

该方法用于得到session对象的创建时间[毫秒]

long getLastAccessedTime()

该方法用于得到session的最后访问时间[毫秒]

int getMaxInactiveInterval()

该方法用于得到session的最大不活动时间[秒]

boolean isNew()

该方法用于session对象是否是一个新的session对象

void setAttribute(String args0, Object  args1);

该方法用于向创建的session对象中保存数据

Object getAttribute(String args0);

该方法用于获取session对象中保存的指定数据

void

removeAttribute(String args0);

该方法用于移除保存在session对象中的指定数据

void invalidate()

该方法用于销毁session对象

例如:

登录操作使用HttpSession对象

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!-- loginservlet -->
<servlet>
	<servlet-name>loginservlte</servlet-name>
	<servlet-class>com.wangxing.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>loginservlte</servlet-name>
	<url-pattern>/loginservlet</url-pattern>
</servlet-mapping>

<!-- loginuiservlet -->
<servlet>
	<servlet-name>loginuiservlet</servlet-name>
	<servlet-class>com.wangxing.servlet.LoginUIServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>loginuiservlet</servlet-name>
	<url-pattern>/loginUI</url-pattern>
</servlet-mapping>

<!-- SuccessUIServlet -->
<servlet>
	<servlet-name>SuccessUIServlet</servlet-name>
	<servlet-class>com.wangxing.servlet.SuccessUIServelt</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>SuccessUIServlet</servlet-name>
	<url-pattern>/SuccessUI</url-pattern>
</servlet-mapping>

<!-- LogoutServlet -->
<servlet>
	<servlet-name>LogoutServlet</servlet-name>
	<servlet-class>com.wangxing.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>LogoutServlet</servlet-name>
	<url-pattern>/logout</url-pattern>
</servlet-mapping>
</web-app>

登录页面的Servlet程序

package com.wangxing.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录页面的Servlet程序
 * @author 14336
 *
 */
public class LoginServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("GET");
		doPost(req, resp);
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("loginservlet POST");
		String name = req.getParameter("username");
		String password = req.getParameter("password");
		if ("张三".equals(name) && "123456".equals(password)) {
			//如果用户名和密码正确则,登录成功,则将用户名传递给登录成功界面
			//有两种方式
			//1.方式一
			req.setAttribute("username", name);
			req.getRequestDispatcher("/SuccessUI").forward(req, resp);
		
		} else {
			//如果用户名和密码不正确
			//将错误信息返回用户登录界面
			req.setAttribute("error", "用户名或密码有误!");
			req.getRequestDispatcher("/loginUI").forward(req, resp);
			
		}
		
		
	}

	
}

通过Servlet创建一个用户登录界面

package com.wangxing.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 通过Servlet创建一个用户登录界面
 * 
 * @author 14336
 *
 */
public class LoginUIServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("loginuiservlet POST");
		// 设置请求和响应的字符集
		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");

		// 通过响应对象获得输出流
		PrintWriter writer = resp.getWriter();
		writer.println("<!DOCTYPE html>");
		writer.println("<html>                                                  ");
		writer.println("<head>                                                  ");
		writer.println("<meta charset='UTF-8'>                                  ");
		writer.println("<title>用户登录</title>                                 ");
		writer.println("</head>                                                 ");
		writer.println("<body>                                                  ");
		writer.println("<center>");
		//得到session对象
		//显示session信息
		HttpSession session = req.getSession();
		showsession(writer,session);
		writer.println("<hr>");
		//提示信息
		if(req.getAttribute("error")!=null){
			writer.println("<font color='red'>"+req.getAttribute("error")+"</font>");
		}
		writer.println("<form action='loginservlet' method='get'>               ");
		writer.println("<table border='1px'>                                    ");
		writer.println("<tr align='center'>                                     ");
		writer.println("<td colspan='2'>                                        ");
		writer.println("<h1>用户登录</h1>                                       ");
		writer.println("</td>                                                   ");
		writer.println("</tr>                                                   ");
		writer.println("<tr align='center'>                                     ");
		writer.println("<td>账号:</td>                                          ");
		writer.println("<td><input type='text' name='username'/></td>           ");
		writer.println("</tr>                                                   ");
		writer.println("<tr align='center'>                                     ");
		writer.println("<td>密码:</td>                                          ");
		writer.println("<td><input type='password' name='password'/></td>       ");
		writer.println("</tr>                                                   ");
		writer.println("<tr align='center'>                                     ");
		writer.println("<td colspan='2'><input type='submit' value='登录'/></td>");
		writer.println("</tr>				                                    ");
		writer.println("</table>                                                ");
		writer.println("</form>                                                 ");
		writer.println("<center>");
		writer.println("</body>                                                 ");
		writer.println("</html>                                                 ");

	}

	/**
	 * 显示session对象信息
	 * @param writer
	 * @param session
	 */
	private void showsession(PrintWriter writer, HttpSession session) {
		writer.println("<table border='1px'>");
		writer.println("<tr align='center'>");
		writer.println("<td colspan='2'><h1>session信息</h1></td>");
		writer.println("</tr>");
		writer.println("<tr align='center'>");
		writer.println("<td>sessionID</td>");
		writer.println("<td>"+session.getId()+"</td>");
		writer.println("</tr>");
		writer.println("<tr align='center'>");
		writer.println("<td>session对象创建的时间</td>");
		writer.println("<td>"+gettime(session.getCreationTime())+"</td>");
		writer.println("</tr>");
		writer.println("<tr align='center'>");
		writer.println("<td>session最后访问时间</td>");
		writer.println("<td>"+gettime(session.getLastAccessedTime())+"</td>");
		writer.println("</tr>");
		writer.println("<tr align='center'>");
		writer.println("<td>session最大不活动时间</td>");
		writer.println("<td>"+session.getMaxInactiveInterval()+"秒</td>");
		writer.println("</tr>");
		writer.println("<tr align='center'>");
		writer.println("<td>session对象是否为新</td>");
		writer.println("<td>"+(session.isNew()?"新":"旧")+"</td>");
		writer.println("</tr>");
		writer.println("</table>");
		
		
	}
/**
 * 得到时间
 * @param creationTime
 * @return
 */
	private String gettime(long creationTime) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
		return simpleDateFormat.format(creationTime);
	}

}

登录成功页面servlet

package com.wangxing.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录成功页面servlet
 * @author 14336
 *
 */
public class SuccessUIServelt extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("successuiservlet POST");
		//设置请求与响应的字符编码
		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");
		PrintWriter writer = resp.getWriter();
		writer.println("<!DOCTYPE html>");
		writer.println("<html>");
		writer.println("<head>");
		writer.println("<meta charset='UTF-8'>");
		writer.println("<title>用户登录</title>");
		writer.println("</head>");
		writer.println("<body>");
		writer.println("<center>");
		//若是直接打开登录成功页面,则跳转到登录页面
		if(req.getAttribute("username")!=null){
			writer.println("<h1>欢迎"+req.getAttribute("username")+"</h1>");
		}else{
			req.getRequestDispatcher("/loginUI").forward(req, resp);
//			resp.sendRedirect("./loginui");
		}
		writer.println("<a href='logout'>安全退出</a>");
		writer.println("</center>");
		writer.println("</body>");
		writer.println("</html>");
		
	}
	

}

退出页面的servlet

package com.wangxing.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogoutServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("logoutservlet POST");
		//销毁Session对象
		req.getSession().invalidate();
		//返回登录页面
		resp.sendRedirect("./loginUI");
	}

}

 

Get与Post的区别?

Get

Post

get通过地址栏传输

post通过报文传输,也可以接收地址栏的数据

get参数有长度限制(受限于url长度)

post无限制,上传文件的时候一定是post

GET产生一个TCP数据包

浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

POST产生两个TCP数据包

浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

安全性差

安全性好

数据查询时,建议用Get方式

数据添加、修改或删除时,建议用Post方式

GET在浏览器回退时是无害的

在浏览器回退时POST会再次提交请求

GET产生的URL地址可以被Bookmark

POST产生的URL地址不可以被Bookmark

GET请求会被浏览器主动cache

POST不会被浏览器主动cache,除非手动设置。

GET请求只能进行url编码

POST支持多种编码方式。

GET请求参数会被完整保留在浏览器历史记录里

POST中的请求参数不会被保留在浏览器历史记录里。

参数的数据类型,GET只接受ASCII字符

POST没有限制

GET参数通过URL传递

POST放在Request body中

中文乱码的处理

1.网页----<meta charset="utf-8">

2.Eclipse---window-->preferences--->General---->workspace---->Text file encoding

3.Tomcat---默认的字符编码“iso8859-1”

服务器/conf目录/server.xml文件

<Connector port="8080" protocol="HTTP/1.1"

               connectionTimeout="20000"

               redirectPort="8443"  URIEncoding="UTF-8"/>

4.URL编码转换

           URLEncoder.encode(String,"utf-8");--转换为URL编码

          URLDecoder.decode(String, "utf-8");---解码

     1.页面提交到Servlet处理程序中的中文为乱码

           Post提交方式  request.setCharacterEncoding(“utf-8”);

           GET方式  String name = new String(name.getBytes(“iso8859-1”),“utf-8”);

      2.Servlet处理程序向页面输出的中文为乱码

         response.setCharacterEncoding("utf-8");

         response.setHeader("Content-Type","text/html;charset=utf-8");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值