【从零开始的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(参数单位是秒);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karshey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值