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报文的首部行用于携带附加信息,可以有零行、一行或者多行。每个首部行包括一个首部行字段名,后面跟一个冒号,然后是一个可选的空格,紧接着是对应的值,最后是CRLF。
不同首部行携带不用类别信息,用于不同目的。
3. 请求空行
空行,用于分隔请求行与请求数据
4. 请求体(正文)
封装POST请求消息的请求参数的
请求体,是请求报文的负荷,可以是文本、图片、视频、HTML 文档、应用程序、电子邮件等。
响应消息数据格式
响应信息由Web服务器发送给浏览器,HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
1. 响应行:
1. 组成:协议/版本 响应状态码 状态码描述
2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。不同状态具有不同含义
1. 状态码都是3位数字
2. 分类:
2. 响应头:
3. 响应空行
4. 响应体:传输的数据
响应空行与相应体的作用与请求报文相同。
请求:request
下面的方法可用在Servlet程序中读取HTTP头。这些方法通过HttpServletRequest对象可用。
请求转发:一种在服务器内部的资源跳转方式
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. 设置状态码为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目录下的资源访问
文件下载小例子
前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 加上虚拟目录--> <a href="/JavaEE_Web_02_01code_war_exploded/img/女.jpg">展示图片</a> <a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.jpg ">下载图片</a> <a href="/JavaEE_Web_02_01code_war_exploded/img/女.png">展示图片</a> <a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.png">下载图片</a> </body> </html>
后端代码
package com.example.JavaEE_Web_02_01code.ServletContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ResourceBundle; /** * @Author: Promsing * @Date: 2021/2/2 - 19:41 * @Description: 文件下载 * @version: 1.0 */ @WebServlet("/DownloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件到内存 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath(filename); FileInputStream fis=new FileInputStream(realPath); //注意:设置response的响应头 String mimeType = servletContext.getMimeType(filename); response.setHeader("content-type",mimeType); response.setHeader("content-disposition","attachment;filename"+filename); //3.将输入流的数据写道输出流中 ServletOutputStream sos = response.getOutputStream(); byte[] bytes=new byte[1024*8]; int len=0; while ((len=fis.read(bytes))!=-1){ sos.write(bytes,0,len); } //管理流 fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }