从零开始的Java开发2-10-4 Servlet与jsp进阶:请求与响应的结构请求转发与响应重定向Cookie

Posted karshey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始的Java开发2-10-4 Servlet与jsp进阶:请求与响应的结构请求转发与响应重定向Cookie相关的知识,希望对你有一定的参考价值。

文章目录

请求与响应的结构

HTTP请求的结构

请求是浏览器向Tomcat服务器所发送的数据包。

  • HTTP请求包含:请求行、请求头、请求体


请求头:

  • Accept-Language:使用语言
  • User-Agent:操作系统和浏览器的环境
  • Content-Length:内容长度

Get没有请求体。(它把这些放在了url中)

演示请求体:get就显示get method;post就显示post method

java:

/**
 * Servlet implementation class RequestServlet
 */
@WebServlet("/request")
public class RequestServlet extends HttpServlet 
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RequestServlet() 
        super();
        // TODO Auto-generated constructor stub
    

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		response.getWriter().println("get method!");
	

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		response.getWriter().println("post method!");
	



html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/Request-struc/request" method="get">
		用户名:<input name="username"/>
		密码:<input name="password" type="password"/>
		<input type="submit"/>
	</form>
</body>
</html>

get时:在浏览器中F12:

对于这个get请求可以看到的信息:

  • Request URL:请求提交的地址
  • Request Method:请求方法
  • Status Code:响应返回的结果是否正确
  • Remote Address:端口
  • Request Headers(请求头)里的:
  • Accept:浏览器能处理的内容
  • Accept-Language:支持的语言环境
  • User-Agent:客户端的操作系统、浏览器
  • Query String Parameters里的:
  • get请求填入的信息

Request URL: http://localhost:8080/Request-struc/request?username=123&password=123
Request Method: GET
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: strict-origin-when-cross-origin

Connection: keep-alive
Content-Length: 13
Date: Tue, 13 Sep 2022 08:07:15 GMT
Keep-Alive: timeout=20

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Host: localhost:8080
Referer: http://localhost:8080/Request-struc/input.html
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
username: 123
password: 123

post时:


数据存放到了Form Data中:

其他请求头的信息基本相同。

巧用请求头开发多端应用

同样的网址在电脑上看和在手机上看是不一样的。

电脑上看到的:

手机:这里是在iPhone SE上的样子。

我们查看User-Agent:

User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1

如果换成安卓系统的:

User-Agent: Mozilla/5.0 (Linux; android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36

桌面环境:

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36

模拟:在不同环境中展现不同的页面

java:这是eclipse自动生成的,我们只需要在doGet里修改一下即可。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		String userAgent=request.getHeader("User-Agent");
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println(userAgent);
	

发布后在浏览器中打开:

Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36


若在选择iPhone SE:

Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1

也就是说,我们可以根据UserAgent的关键字来判断是PC还是手机。

java:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		String userAgent=request.getHeader("User-Agent");
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println(userAgent);
		
		String output="";
		
		//是PC端
		if(userAgent.indexOf("Windows")!=-1) 
			output="<h1>PC端!</h1>";
		else if(userAgent.indexOf("iPhone")!=-1||userAgent.indexOf("Andorid")!=-1) 
			//移动端
			output="<h1>移动端!</h1>";
		
		
		response.getWriter().println(output);
	

则PC端:

移动端:

响应的结构

HTTP响应包含:

  • 响应行
  • 响应头
  • 响应体

响应行和响应头:(Headers)

HTTP/1.1 200
Content-Type: text/html;charset=utf-8
Content-Length: 130
Date: Tue, 13 Sep 2022 09:06:00 GMT
Keep-Alive: timeout=20
Connection: keep-alive


响应体:(Response)

Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
<h1>PC端!</h1>

HTTP常见状态码

什么时候出现其他状态码(可能):

  • 404:输错了网址,url找不到对应的地址。
  • 500:java源代码出错了。

ContentType的作用

ContentType决定浏览器采用何种方式对响应体进行处理。

举个例子

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		String output="<h1><a href='www.baidu.com'><span>百度</span></a></h1>";
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println(output);
	


若改成纯文本:

response.setContentType("text/plain;charset=utf-8");


若改成xml:

response.setContentType("text/xml;charset=utf-8");

请求转发与响应重定向

多个Servlet(JSP)之间跳转有两种方式:

  • 请求转发:request.getRequestDispatcher().forward()
  • 响应重定向:response.sendRedirect()

现在有一个场景:登录淘宝,在登录之后会自动刷新页面。
这里就有跳转。可以用两个Servlet来完成:一个是用户登录,一个是返回页面。
即,用CheckLogin来表示用户登录,登录后就跳转到Index。

请求转发的例子

java:CheckLogin,它的url-pattern是/direct/check

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		System.out.println("用户登陆成功!");
		//请求派发器
		//实现了请求转发的功能
		request.getRequestDispatcher("/direct/index").forward(request, response);
	

java:index,它的url-pattern是/direct/index

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		response.getWriter().println("This is an index page!");	
	

发布工程后,在浏览器中输入网址:http://localhost:8080/servlet_advanced/direct/check

显示:这里的url是check

响应重定向的例子

CheckLogin:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		System.out.println("用户登陆成功!");
	
		//响应重定向:需要增加contextPath
		response.sendRedirect("/servlet_advanced/direct/index");
	

url是index

请求转发与响应重定向的原理

请求转发

  • 是服务器跳转,只会产生一次请求
  • 语句:request.getRequestDispatcher().forward()


响应重定向

  • 重定向是浏览器端跳转,会产生两次请求
  • 语句:response.sendRedirect()

设置请求自定义属性

  • 请求允许创建自定义属性
  • 设置请求属性:request.setAttribute(属性名,属性值)
  • 获取请求属性:Object attr=request.getAttribute(属性名)

CheckLogin:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		System.out.println("用户登陆成功!");
		
		//设置属性
		request.setAttribute("username", "admin");
		
		//请求派发器
		//实现了请求转发的功能
		request.getRequestDispatcher("/direct/index").forward(request, response);
	

index:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		//登录成功后输出显示属性值
		String name=(String)request.getAttribute("username");
		
		response.getWriter().println("This is an index page!"+name);	
	

显示:

显然,CheckLogin和index里的request是同一个。

如果我们用响应重定向呢?
显示:


由我们上面提过的原理可知,请求转发只有一个请求,而响应重定向有两个请求:且请求1会被销毁,则请求1的内部属性也会销毁。

浏览器相关

浏览器Cookie

Cookie

  • Cookie是浏览器保存在本地的文本内容
  • 常用于保存登陆状态、用户资料等小文本
  • 具有时效性,Cookie内容会伴随请求发送给Tomcat

举个例子:7天内自动登录,就是用了Cookie。

以谷歌浏览器为例,我们查看一下它的Cookie存在哪里

路径:C:\\Users\\我的用户名\\AppData\\Local\\Google\\Chrome\\User Data

里面有一个Safe Browsing Cookies,我们把它用记事本打开:
一堆乱码,因为加密了


不影响我们用程序使用它。

举例:设置Cookie

java:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException 
		System.out.println("用户登录成功!");

		// 创建Cookie,参数:Cookie名称,要保存的数据
		Cookie cookie = new Cookie("user", "admin");

		// 把这个Cookie保存到浏览器中
		response.addCookie(cookie);

		// 输出一下
		response.getWriter().println("login!");
	

在浏览器中输入:http://localhost:8080/servlet_advanced/cookies/login

则显示:login!

保存的Cookie:

举例:读取Cookie

主要语句:request.getCookies();

java:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException 
		Cookie[] cs = request.getCookies();

		// 遍历输出所有cookies
		for (Cookie css : cs) 
			System.out.println(css.getName() + ": " + css.getValue());
		
	

控制台输出:

user: admin

Cookie时效性

默认是浏览器窗口:浏览器关闭,Cookie就自动销毁。

设置Cookie时效性:cookie.setMaxAge(参数单位是秒);

以上是关于从零开始的Java开发2-10-4 Servlet与jsp进阶:请求与响应的结构请求转发与响应重定向Cookie的主要内容,如果未能解决你的问题,请参考以下文章

从零开始的Java开发2-10-3 JSP入门:JSP介绍语法和页面重用

温故知新从零开始搭建 java web项目

从零开始手写Tomcat的教程5节---servlet容器

零基础学java应该从哪里开始?

从零开始002构建简易servlet完成发布与访问

Java开发从零开始!java游戏服务器开发教程