JavaWeb跳转以及会话跟踪

Servlet的跳转

     1.forward---RequestDispatcher接口的

          forward(ServletRequest request,ServletResponse response)---该方法用于将请求从一个 Servlet 传递给另一个 Web 资源【Servlet程序/html/JSP】。【请求转发】

          forward属于RequestDispatcher接口的

          HttpServletRequest接口从ServletRequest接口中继承了一个获取 RequestDispatcher 对象的方法RequestDispatcher getRequestDispatcher (String path).

          参数String path---目标路径【必须以“/”开头,用于表示当前 Web 应用的根目录】

          需要注意的是,WEB-INF 目录中的内容对 RequestDispatcher 对象也是可见的。因此,传递给 getRequestDispatcher(String path) 方法的资源可以是 WEB-INF 目录中的文件

          RequestDispatcher接口对象=HttpServletRequest接口对象.getRequestDispatcher (String path);

          RequestDispatcher接口对象.forward(ServletRequest request,ServletResponse response).

          通过HttpServletRequest对象传递数据的。

          HttpServletRequest对象的方法

          void setAttribute(String name,Object o) 用于将一个对象与一个名称关联后存储到 ServletRequest 对象中

          Object getAttribute(String name) 用于从 ServletRequest 对象中返回指定名称的属性对象

          void removeAttribute(String name) 用于从 ServletRequest 对象中删除指定名称的属性

    

例如:

package com.wangxing.servlet;
import java.io.IOException;

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

public class OneServlet 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("------------------");
		//forward(ServletRequest request,ServletResponse response);该方法用于将请求从一个servlet传递给另一个web资源【Servlet程序/html/JSP】
		//forward(ServletRequest req,ServletRresponse resp)方法是RequestDispatcher中的方法
		//HttpServletRequest中有获得RequestDispatcher对象的方法
		//getRequestDispatcher();
		/*
		RequestDispatcher requestDispatcher = req.getRequestDispatcher("/test.html");
		requestDispatcher.forward(req, resp);
		
		req.getRequestDispatcher("/onther").forward(req, resp);
		*/
		//void setAttribute(String name,Object o);用于将一个对象与另一对象关联后存储到ServletRequest对象中
		req.setAttribute("name", "zhangsan");
		
		req.getRequestDispatcher("/other").forward(req, resp);
	}
	
}
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 OtherServlet 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 {
		//Object getAttribute(String name);用于从ServletRequest对象中返回指定名称的属性对象
		String name = (String) req.getAttribute("name");
		System.out.println("OtherServlet----name==" + name);
	}
	
}

      2.Redirect----HttpServletRespone.sendRedirect()[重定向]

            HttpServletResponse 接口定义了一个 sendRedirect(String path) 方法.将请求从一个 Servlet 传递给另一个 Web 资源【Servlet程序/html/JSP】

例如:

package com.wangxing.servlet;

import java.io.IOException;

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

public class OneServlet 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("---------------");
		//sendRedirect(String path);方法请求从一个Servlet传递给另一个Web资源【Servlet程序/html/JSP】
		//resp.sendRedirect("test.html");
		//resp.sendRedirect("/test.html");错误
		
		req.setAttribute("name", "lisi");
		resp.sendRedirect("other");
	}
	
}
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 OtherServlet 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 {
		//Object getAttribute(String name);用于从ServletRequest对象中返回指定名称的属性值
		String name = (String) req.getAttribute("name");
		//sendRedirect不能传递数据因为他是重定位
		System.out.println("OtherServlet--name=="+name);
		
	}
	
}

            上面的测试是由Servlet程序访问Html/其他的Servlet

            我们能不能通过html访问Servlet程序?

            能,有三种方式

            1.通过html的表单元素

            2.通过html的超链接

            3.通过javascript的ajax发送异步请求

      例如:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<!-- 
	<center>
		<form action="login" method="post">
			<table border="1px">
				<tr align="center">
					<td colspan="2"><h1>用户登录</h1></td>
				</tr>
				<tr align="center">
					<td>账号:</td>
					<td><input type="text" name="username"/></td>
				</tr>
				<tr align="center">
					<td>密码:</td>
					<td><input type="password" name="password"/></td>
				</tr>
				<tr align="center">
					<td colspan="2"><input type="submit" value="登录"/></td>
				</tr>
			</table>
		</form>
	</center>
	 -->
	 <h1><a href="login?username=zhangsan&password=123">用户登录</a></h1>
</body>
</html>

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 LoginServlet 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 {
		//得到账号和密码
		String  name=req.getParameter("username");
		String  pass=req.getParameter("password");
		System.out.println("name=="+name+" "+"pass=="+pass);
	}
}

区别:

RequestDispatcher.forward(req, resp)

HttpServletRespone.sendRedirect()

请求转发

重定向

使用的是同一个请求对象

使用的是不同的请求对象

浏览器地址栏中的url不会变

浏览器地址栏中的url会变化

可以通过HttpServletRequest对象传递数据

不可以通过HttpServletRequest对象传递数据

设置目标路径时“/”可以写也可以不写

设置目标路径时“/”一定不能写

依赖ServletRequest接口

依赖HttpServletRespone对象

会话跟踪

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

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

     2.什么是会话跟踪?

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

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

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

               https://blog.csdn.net/qq_33098039/article/details/78184535?sessionid=123456

               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对象

package com.wangxing.servlet;

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

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 Administrator
 *
 */
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 {
		//设置字符集
		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");
		//得到输出流
		PrintWriter out = resp.getWriter();
		out.println("<!DOCTYPE html> "); 
		out.println("<html>"); 
		out.println("<head>"); 
		out.println("<meta charset=\"UTF-8\">"); 
		out.println("<title>用户登录</title>"); 
		out.println("</head>"); 
		out.println("<body>"); 
		out.println("<center>"); 
		//得到session对象
		HttpSession session = req.getSession();
		//显示session信息
		showsessioninfo(out,session);
		out.println("<hr>");
		Object errorobj = req.getSession().getAttribute("error");
		if(errorobj != null){
			out.println("<font color=\"red\">"+(String)errorobj+"</font>");
		}
		out.println("<form action=\"login\" method=\"post\">"); 
		out.println("<table border=\"1px\">"); 
		out.println("<tr align=\"center\">"); 
		out.println("<td colspan=\"2\"><h1>用户登录</h1></td>"); 
		out.println("</tr>"); 
		out.println("<tr align=\"center\">"); 
		out.println("<td>账号:</td>"); 
		out.println("<td><input type=\"text\" name=\"username\"/></td>"); 
		out.println("</tr>"); 
		out.println("<tr align=\"center\">"); 
		out.println("<td>密码:</td>"); 
		out.println("<td><input type=\"password\" name=\"password\"/></td>"); 
		out.println("</tr>"); 
		out.println("<tr align=\"center\">"); 
		out.println("<td colspan=\"2\"><input type=\"submit\" value=\"登录\"/></td");
		out.println("</tr>"); 
		out.println("</table>"); 
		out.println("</form>"); 
		out.println("</center>"); 
		out.println("</body>"); 
		out.println("</html>"); 
		out.close();	
	}
	/**
	 * 显示session信息
	 * @param out
	 * @param session
	 */
	private void showsessioninfo(PrintWriter out, HttpSession session) {
		out.println("<table border=\"1px\">");
		out.println("<tr align=\"center\">");
		out.println("<td colspan=\"2\">");
		out.println("<h1>session信息</h1>");
		out.println("</td>");
		out.println("</tr>");
		out.println("<tr align=\"center\">");
		out.println("<td>sessionID:</td>");
		out.println("<td>"+session.getId()+"</td>");
		out.println("</tr>");
		out.println("<tr align=\"center\">");
		out.println("<td>session对象的创建时间:</td>");
		out.println("<td>"+gettime(session.getCreationTime())+"</td>");
		out.println("</tr>");
		out.println("<tr align=\"center\">");
		out.println("<td>session的最后访问时间:</td>");
		out.println("<td>"+gettime(session.getLastAccessedTime())+"</td>");
		out.println("</tr>");
		out.println("<tr align=\"center\">");
		out.println("<td>session的最大不活动时间:</td>");
		out.println("<td>"+session.getMaxInactiveInterval()+"秒</td>");
		out.println("</tr>");
		out.println("<tr align=\"center\">");
		out.println("<td>session对象是否为新:</td>");
		out.println("<td>"+session.isNew()+"</td>");
		out.println("</tr>");
		out.println("</table>");	
	}
	/**
	 * 得到时间
	 * @param creationTime
	 * @return
	 */
	private String gettime(long creationTime) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
		return sdf.format(new Date(creationTime));
	}
	
}
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;

/**
 * 处理登录业务
 * @author Administrator
 *
 */
public class LoginServlet 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 {
		//得到账号和密码
		String name = req.getParameter("username");
		String pass = req.getParameter("password");
		if("zhangsan".equals(name) & "123456".equals(pass)){
			//req.setAttribute("username", name);
			//req.getRequestDispatcher("success").forward(req, resp);
			req.getSession().setAttribute("username", name);
			resp.sendRedirect("success");
		}else{
			//req.setAttribute("error", "用户名密码有误");
			//req.getRequestDispatcher("loginui").forward(req, resp);
			req.getSession().setAttribute("error", "用户名密码有误!");
			resp.sendRedirect("loginui");
		}
	}
	
}
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 Administrator
 *
 */
public class SuccessUIServlet 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 {
		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");
		PrintWriter out = resp.getWriter();
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset=\"UTF-8\">");
		out.println("<title>登录成功</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<center>");
		Object userObj = req.getSession().getAttribute("username");
		if(userObj == null){
			//req.getRequestDispatcher("loginui");
			resp.sendRedirect("loginui");
		}else{
			out.println("<h1>"+(String)userObj+",登录成功</h1>");
		}
		out.println("</center>");
		out.println("</body>");
		out.println("</html>");
		out.close();
	}
	
}
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;

/**
 * 处理退出业务 
 * @author Administrator
 *
 */
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 {
		req.getSession().invalidate();
		resp.sendRedirect("loginui");
	}
	
}

               3.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中

               4.中文乱码的处理

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

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

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

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

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

                    connectionTimeout="20000"

                    redirectPort="8443"  URIEncoding="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");

猜你喜欢

转载自blog.csdn.net/m0_49935332/article/details/115017642