zoukankan      html  css  js  c++  java
  • Request与Response详解

     HTTP协议

     

    简介

    HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。

    HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

    HTTP 工作原理

    HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

    Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。

    Web服务器根据接收到的请求后,向客户端发送响应信息。

    HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

    HTTP三点注意事项:

    • HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
    • HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
    • HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
    • 浏览器显示的内容都有 HTML、XML、GIF、Flash 等,浏览器是通过 MIME Type 区分它们,决定用什么内容什么形式来显示。

    请求消息数据格式

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。

    1. 请求行

    请求行中的“方法”实际上就是命令,表示客户端希望服务器对URL指定的资源执行的操作(或动作),即表示服务器做什么;URL定位所请求的资源;协议版本用于通告服务器客户端所使用的HTTP版本号。

    常见的请求方式有两种:          

             GET:

                         1. 请求参数在请求行中,在url后。

                         2. 请求的url长度有限制的

                         3. 不太安全

            POST:

                        1. 请求参数在请求体中

                        2. 请求的url长度没有限制的

                        3. 相对安全

    2. 请求头

    http请求头(Header)参数详解:https://www.cnblogs.com/lspbk/p/14431188.html

    HTTP报文的首部行用于携带附加信息,可以有零行、一行或者多行。每个首部行包括一个首部行字段名,后面跟一个冒号,然后是一个可选的空格,紧接着是对应的值,最后是CRLF。

    不同首部行携带不用类别信息,用于不同目的。

    头信息描述
    Accept 这个头信息指定浏览器或其他客户端可以处理的 MIME 类型。值 image/png 或 image/jpeg 是最常见的两种可能值。
    Accept-Charset 这个头信息指定浏览器可以用来显示信息的字符集。例如 ISO-8859-1。
    Accept-Encoding 这个头信息指定浏览器知道如何处理的编码类型。值 gzip 或 compress 是最常见的两种可能值。
    Accept-Language 这个头信息指定客户端的首选语言,在这种情况下,Servlet 会产生多种语言的结果。例如,en、en-us、ru 等。
    Authorization 这个头信息用于客户端在访问受密码保护的网页时识别自己的身份。
    Connection 这个头信息指示客户端是否可以处理持久 HTTP 连接。持久连接允许客户端或其他浏览器通过单个请求来检索多个文件。值 Keep-Alive 意味着使用了持续连接。
    Content-Length 这个头信息只适用于 POST 请求,并给出 POST 数据的大小(以字节为单位)。
    Cookie 这个头信息把之前发送到浏览器的 cookies 返回到服务器。
    Host 这个头信息指定原始的 URL 中的主机和端口。
    If-Modified-Since 这个头信息表示只有当页面在指定的日期后已更改时,客户端想要的页面。如果没有新的结果可以使用,服务器会发送一个 304 代码,表示 Not Modified 头信息。
    If-Unmodified-Since 这个头信息是 If-Modified-Since 的对立面,它指定只有当文档早于指定日期时,操作才会成功。
    Referer 这个头信息指示所指向的 Web 页的 URL。例如,如果您在网页 1,点击一个链接到网页 2,当浏览器请求网页 2 时,网页 1 的 URL 就会包含在 Referer 头信息中。
    User-Agent 这个头信息识别发出请求的浏览器或其他客户端,并可以向不同类型的浏览器返回不同的内容。

    3. 请求空行

                空行,用于分隔请求行与请求数据

    4. 请求体(正文)

                 封装POST请求消息的请求参数的

                请求体,是请求报文的负荷,可以是文本、图片、视频、HTML 文档、应用程序、电子邮件等。

    响应消息数据格式

    响应信息由Web服务器发送给浏览器,HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

    1. 响应行:

                  1. 组成:协议/版本 响应状态码 状态码描述

                  2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。不同状态具有不同含义

                        1. 状态码都是3位数字 

                        2. 分类:

    分类分类描述
    1** 信息,服务器收到请求,需要请求者继续执行操作
    2** 成功,操作被成功接收并处理。代表:200
    3** 重定向,需要进一步的操作以完成请求。代表:302(重定向),304(访问缓冲)
    4** 客户端错误,请求包含语法错误或无法完成请求。代表:404(请求路径没有对应的资源),405(请求方式没有对应的doXxx方法)
    5** 服务器错误,服务器在处理请求的过程中发生了错误。代表:500(服务器内部出现异常)

    2. 响应头:

    头信息描述
    Allow 这个头信息指定服务器支持的请求方法(GET、POST 等)。
    Cache-Control 这个头信息指定响应文档在何种情况下可以安全地缓存。可能的值有:public、private 或 no-cache 等。Public 意味着文档是可缓存,Private 意味着文档是单个用户私用文档,且只能存储在私有(非共享)缓存中,no-cache 意味着文档不应被缓存。
    Connection 这个头信息指示浏览器是否使用持久 HTTP 连接。值 close 指示浏览器不使用持久 HTTP 连接,值 keep-alive 意味着使用持久连接。
    Content-Disposition 这个头信息可以让您请求浏览器要求用户以给定名称的文件把响应保存到磁盘。
    Content-Encoding 在传输过程中,这个头信息指定页面的编码方式。
    Content-Language 这个头信息表示文档编写所使用的语言。例如,en、en-us、ru 等。
    Content-Length 这个头信息指示响应中的字节数。只有当浏览器使用持久(keep-alive)HTTP 连接时才需要这些信息。
    Content-Type 这个头信息提供了响应文档的 MIME(Multipurpose Internet Mail Extension)类型。
    Expires 这个头信息指定内容过期的时间,在这之后内容不再被缓存。
    Last-Modified 这个头信息指示文档的最后修改时间。然后,客户端可以缓存文件,并在以后的请求中通过 If-Modified-Since 请求头信息提供一个日期。
    Location 这个头信息应被包含在所有的带有状态码的响应中。在 300s 内,这会通知浏览器文档的地址。浏览器会自动重新连接到这个位置,并获取新的文档。
    Refresh 这个头信息指定浏览器应该如何尽快请求更新的页面。您可以指定页面刷新的秒数。
    Retry-After 这个头信息可以与 503(Service Unavailable 服务不可用)响应配合使用,这会告诉客户端多久就可以重复它的请求。
    Set-Cookie 这个头信息指定一个与页面关联的 cookie。

    3. 响应空行

     

    4. 响应体:传输的数据

    响应空行与相应体的作用与请求报文相同。

    请求:request

    下面的方法可用在Servlet程序中读取HTTP头。这些方法通过HttpServletRequest对象可用。

    序号方法 & 描述
    1 Cookie[] getCookies()
    返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。
    2 Enumeration getAttributeNames()
    返回一个枚举,包含提供给该请求可用的属性名称。
    3 Enumeration getHeaderNames()
    返回一个枚举,包含在该请求中包含的所有的头名。
    4 Enumeration getParameterNames()
    返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
    5 HttpSession getSession()
    返回与该请求关联的当前 session 会话,或者如果请求没有 session 会话,则创建一个。
    6 HttpSession getSession(boolean create)
    返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话。
    7 Locale getLocale()
    基于 Accept-Language 头,返回客户端接受内容的首选的区域设置。
    8 Object getAttribute(String name)
    以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。
    9 ServletInputStream getInputStream()
    使用 ServletInputStream,以二进制数据形式检索请求的主体。
    10 String getAuthType()
    返回用于保护 Servlet 的身份验证方案的名称,例如,"BASIC" 或 "SSL",如果JSP没有受到保护则返回 null。
    11 String getCharacterEncoding()
    返回请求主体中使用的字符编码的名称。
    12 String getContentType()
    返回请求主体的 MIME 类型,如果不知道类型则返回 null。
    13 String getContextPath()
    返回指示请求上下文的请求 URI 部分。
    14 String getHeader(String name)
    以字符串形式返回指定的请求头的值。
    15 String getMethod()
    返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
    16 String getParameter(String name)
    以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。
    17 String getPathInfo()
    当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息。
    18 String getProtocol()
    返回请求协议的名称和版本。
    19 String getQueryString()
    返回包含在路径后的请求 URL 中的查询字符串。
    20 String getRemoteAddr()
    返回发送请求的客户端的互联网协议(IP)地址。
    21 String getRemoteHost()
    返回发送请求的客户端的完全限定名称。
    22 String getRemoteUser()
    如果用户已通过身份验证,则返回发出请求的登录用户,或者如果用户未通过身份验证,则返回 null。
    23 String getRequestURI()
    从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
    24 String getRequestedSessionId()
    返回由客户端指定的 session 会话 ID。
    25 String getServletPath()
    返回调用 JSP 的请求的 URL 的一部分。
    26 String[] getParameterValues(String name)
    返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。
    27 boolean isSecure()
    返回一个布尔值,指示请求是否使用安全通道,如 HTTPS。
    28 int getContentLength()
    以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。
    29 int getIntHeader(String name)
    返回指定的请求头的值为一个 int 值。
    30 int getServerPort()
    返回接收到这个请求的端口号。
    31 int getParameterMap()
    将参数封装成 Map 类型。

    请求转发:一种在服务器内部的资源跳转方式

         1. 通过request对象获取请求转发器对象:

                      RequestDispatcher getRequestDispatcher(String path)

         2. 使用RequestDispatcher对象来进行转发:

                     forward(ServletRequest request, ServletResponse response) 

    转发到另个类,需要request.getAttribute("转发的内容的名字");

    共享数据

      域对象:一个有作用范围的对象,可以在范围内共享数据

            request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

               方法:

                        1. void setAttribute(String name,Object obj):存储数据

                        2. Object getAttitude(String name):通过键获取值

                        3. void removeAttribute(String name):通过键移除键值对

    响应:response对象

    下面的方法可用于在 Servlet 程序中设置 HTTP 响应报头。这些方法通过 HttpServletResponse 对象可用。

    序号方法 & 描述
    1 String encodeRedirectURL(String url)
    为 sendRedirect 方法中使用的指定的 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。
    2 String encodeURL(String url)
    对包含 session 会话 ID 的指定 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。
    3 boolean containsHeader(String name)
    返回一个布尔值,指示是否已经设置已命名的响应报头。
    4 boolean isCommitted()
    返回一个布尔值,指示响应是否已经提交。
    5 void addCookie(Cookie cookie)
    把指定的 cookie 添加到响应。
    6 void addDateHeader(String name, long date)
    添加一个带有给定的名称和日期值的响应报头。
    7 void addHeader(String name, String value)
    添加一个带有给定的名称和值的响应报头。
    8 void addIntHeader(String name, int value)
    添加一个带有给定的名称和整数值的响应报头。
    9 void flushBuffer()
    强制任何在缓冲区中的内容被写入到客户端。
    10 void reset()
    清除缓冲区中存在的任何数据,包括状态码和头。
    11 void resetBuffer()
    清除响应中基础缓冲区的内容,不清除状态码和头。
    12 void sendError(int sc)
    使用指定的状态码发送错误响应到客户端,并清除缓冲区。
    13 void sendError(int sc, String msg)
    使用指定的状态发送错误响应到客户端。
    14 void sendRedirect(String location)
    使用指定的重定向位置 URL 发送临时重定向响应到客户端。
    15 void setBufferSize(int size)
    为响应主体设置首选的缓冲区大小。
    16 void setCharacterEncoding(String charset)
    设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。
    17 void setContentLength(int len)
    设置在 HTTP Servlet 响应中的内容主体的长度,该方法设置 HTTP Content-Length 头。
    18 void setContentType(String type)
    如果响应还未被提交,设置被发送到客户端的响应的内容类型。
    19 void setDateHeader(String name, long date)
    设置一个带有给定的名称和日期值的响应报头。
    20 void setHeader(String name, String value)
    设置一个带有给定的名称和值的响应报头。
    21 void setIntHeader(String name, int value)
    设置一个带有给定的名称和整数值的响应报头。
    22 void setLocale(Locale loc)
    如果响应还未被提交,设置响应的区域。
    23 void setStatus(int sc)
    为该响应设置状态码。

    重定向 

           1. 设置状态码为302

                    response.setStatus(302);

           2.设置响应头location

                    response.setHeader("location","/day15/responseDemo2");

            简单的重定向方法

                    response.sendRedirect("/day15/responseDemo2");

            乱码问题:

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

    ServletContext对象:

     

    1. 概念:

              代表整个web应用,可以和程序的容器(服务器)来通信

    2. 获取:

            1. 通过request对象获取

                  request.getServletContext();

            2. 通过HttpServlet获取

                  this.getServletContext();

    3. 功能:

            1. 获取MIME类型:

                  MIME类型:在互联网通信过程中定义的一种文件数据类型

                      格式: 大类型/小类型   text/html        image/jpeg

                    获取:String getMimeType(String file)  

            2. 域对象:共享数据

                1. setAttribute(String name,Object value)

                2. getAttribute(String name)

                3. removeAttribute(String name)

                      ServletContext对象范围:所有用户所有请求的数据

            3. 获取文件的真实(服务器)路径

                1. 方法:String getRealPath(String path)  

                    String b = context.getRealPath("/b.txt");//web目录下资源访问

                    String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访

                    String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问

    文件下载小例子

     

    1、前端代码

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4 <meta charset="UTF-8">
     5 <title>Title</title>
     6 </head>
     7 <body>
     8 <!-- 加上虚拟目录-->
     9 <a href="/JavaEE_Web_02_01code_war_exploded/img/女.jpg">展示图片</a>
    10 <a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.jpg ">下载图片</a>
    11 <a href="/JavaEE_Web_02_01code_war_exploded/img/女.png">展示图片</a>
    12 <a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.png">下载图片</a>
    13 </body>
    14 </html>
    复制代码

    2、后端代码

    复制代码
     1 package com.example.JavaEE_Web_02_01code.ServletContext;
     2 
     3 import javax.servlet.ServletContext;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.ServletOutputStream;
     6 import javax.servlet.annotation.WebServlet;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 import java.io.File;
    11 import java.io.FileInputStream;
    12 import java.io.IOException;
    13 import java.io.InputStream;
    14 import java.util.ResourceBundle;
    15 
    16 /**
    17 * @Author: Promsing
    18 * @Date: 2021/2/2 - 19:41
    19 * @Description: 文件下载
    20 * @version: 1.0
    21 */
    22 
    23 @WebServlet("/DownloadServlet")
    24 public class DownloadServlet extends HttpServlet {
    25   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    26     //1.获取请求参数,文件名称
    27     String filename = request.getParameter("filename");
    28     //2.使用字节输入流加载文件到内存
    29     ServletContext servletContext = this.getServletContext();
    30     String realPath = servletContext.getRealPath(filename);
    31     FileInputStream fis=new FileInputStream(realPath);
    32     //注意:设置response的响应头
    33     String mimeType = servletContext.getMimeType(filename);
    34     response.setHeader("content-type",mimeType);
    35     response.setHeader("content-disposition","attachment;filename"+filename);
    36     //3.将输入流的数据写道输出流中
    37     ServletOutputStream sos = response.getOutputStream();
    38     byte[] bytes=new byte[1024*8];
    39     int len=0;
    40     while ((len=fis.read(bytes))!=-1){
    41     sos.write(bytes,0,len);
    42     }
    43     //管理流
    44     fis.close();
    45   }
    46  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 47     this.doPost(request, response); 48   } 49 }
    复制代码

     转载至JavaWeb之Request与Response详解:https://blog.csdn.net/promsing/article/details/113618924

    小丑竟是我自己
    作者:拾瑾
    个性签名:愿历经千帆,归来仍少年.
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    Object类入门这一篇就够了!
    什么是Java内部类?
    Spring Cloud Alibaba基础教程:支持的几种服务消费方式(RestTemplate、WebClient、Feign)
    Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现
    Spring Cloud Stream同一通道根据消息内容分发不同的消费逻辑
    Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)
    Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)
    Spring Cloud Stream消费失败后的处理策略(二):自定义错误处理逻辑
    Spring Cloud Stream消费失败后的处理策略(一):自动重试
    Spring Cloud Stream如何消费自己生产的消息?
  • 原文地址:https://www.cnblogs.com/ayoung/p/14452398.html
Copyright © 2011-2022 走看看