• 【从零开始的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!");
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    html:

    DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title heretitle>
    head>
    <body>
    	<form action="/Request-struc/request" method="get">
    		用户名:<input name="username"/>
    		密码:<input name="password" type="password"/>
    		<input type="submit"/>
    	form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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
    
    • 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
    
    • 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
    
    • 1

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

    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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    发布后在浏览器中打开:

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

    在这里插入图片描述
    若在选择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
    
    • 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="

    PC端!

    "
    ; }else if(userAgent.indexOf("iPhone")!=-1||userAgent.indexOf("Andorid")!=-1) { //移动端 output="

    移动端!

    "
    ; } response.getWriter().println(output); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    则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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    响应体:(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>
    
    • 1
    • 2

    在这里插入图片描述

    HTTP常见状态码
    在这里插入图片描述
    什么时候出现其他状态码(可能):

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

    ContentType的作用

    ContentType决定浏览器采用何种方式对响应体进行处理。
    在这里插入图片描述
    举个例子

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String output="

    百度

    "
    ; response.setContentType("text/html;charset=utf-8"); response.getWriter().println(output); }
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    若改成纯文本:

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

    在这里插入图片描述
    若改成xml:

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

    在这里插入图片描述

    请求转发与响应重定向

    多个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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

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

    发布工程后,在浏览器中输入网址: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");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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);	
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    显示:
    在这里插入图片描述
    显然,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!");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在浏览器中输入: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());
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    控制台输出:

    user: admin
    
    • 1

    Cookie时效性

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

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

  • 相关阅读:
    idea导入javaweb变成灰色
    CV&NLP基础12之自然语言处理引入
    docker部署的nginx配置ssl证书https
    C++ Reference: Standard C++ Library reference: C Library: cfenv: fegetround
    【Hack The Box】linux练习-- Haircut
    【前端】不同类型数据组装拼接
    BIOS 如何确定引导扇区的位置
    第十五章 I/O(输入/输出)流
    第一章 C语言知识点(程序)
    Windows环境下Apache安装部署说明及常见问题解决
  • 原文地址:https://blog.csdn.net/karshey/article/details/126835120