Http协议
什么是Http协议?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写。HTTP 协议和 TCP/IP 协议族内的其他众多的协议相同, 用于客户端和服务器之间的通信。请求访问文本或图像等资源的一端称为客户端, 而提供资源响应的一端称为服务器端。
协议:是指对方,或者多方,相互约定好,大家都要遵守的规则,叫协议。
所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。 HTTP 协议中的数据又叫报文。
请求HTTP协议格式
- 客户端给服务器发送数据叫请求。
- 服务器给客户端回传数据叫响应。
- 请求又分为 GET 请求,和 POST 请求两种
GET请求
-
请求行
- 请求的方式 -->GET
- 请求的资源路径**[+?+请求参数]**
- 请求的协议的版本号 -->HTTP/1.1
-
请求头
key:value组成不同的键值对,表示不同的含义
POST请求
-
请求行
- 请求的方式 -->POST
- 请求的资源路径**[+?+请求参数]**
- 请求的协议的版本号 -->HTTP/1.1
-
请求头
key:value组成不同的键值对,表示不同的含义
-
空行
-
请求体:发送给服务器的数据
常用请求头说明
- Accept: 表示客户端可以接收的数据类型
- Accpet-Languege: 表示客户端可以接收的语言类型
- User-Agent: 表示客户端浏览器的信息
- Host: 表示请求时的服务器 ip 和端口
区分GET请求与POST请求
- GET请求:
- form 标签method=get
- a标签
- link标签引入css
- script标签引入js
- img标签引入图片
- iframe引入html页面
- 在浏览器地址栏中输入地址后回车
- POST请求:
- form标签method=post
响应的HTTP协议格式
- 响应行
- 响应的协议和版本号
- 响应状态码
- 响应状态描述符
- 响应头
- key:value,不同的响应头,有其不同的含义
- 响应体:回传给客户端的数据
常用响应码说明
响应码 | 解释 |
---|---|
200 | 表示请求成功 |
302 | 表示请求重定向 |
404 | 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误) |
500 | 表示服务器已经收到请求,但是服务器内部错误(代码错误) |
MIME 类型说明
文件 | MIME类型 | Content-Type |
---|---|---|
超文本标记语言文本 | .html, .htm | text/html |
普通文本 | .txt | text/plain |
RTF 文本 | .rtf | application/rtf |
GIF 图形 | .gif | image/gif |
JPEG 图形 | .jpeg,.jpg | image/jpeg |
au 声音文件 | .au | audio/basic |
MIDI 音乐文件 | mid,.midi | audio/midi,audio/x-midi |
RealAudio 音乐文件 | .ra, .ram | audio/x-pn-realaudio |
MPEG 文件 | .mpg,.mpeg | video/mpeg |
AVI 文件 | .avi | video/x-msvideo |
GZIP 文件 | .gz | application/x-gzip |
TAR 文件 | .tar | application/x-tar |
谷歌浏览器如何查看HTTP协议:
其他浏览器查询方式与其相似
HttpServletRequest类
作用
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的 信息。
常用方法
方法 | 描述 |
---|---|
getRequestURI() | 获取请求的资源路径 |
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
getRemoteHost() | 获取客户端的 ip地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数(多个值的时候使用) |
getMethod() | 获取请求的方式 GET 或 POST |
setAttribute(key, value) | 设置域数据 |
getAttribute(key) | 获取域数据 |
getRequestDispatcher() | 获取请求转发对象 |
相关使用:
public class RequestServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//getRequestURI()获取请求的资源路径
System.out.println("URI===>" + request.getRequestURI());
//getRequestURL()获取请求的统一资源定位符(绝对路径)
System.out.println("URL===>" + request.getRequestURL());
//getRemoteHost()获取客户端的 ip地址
System.out.println("ip地址===>" + request.getRemoteHost());
//getHeader()获取请求头
System.out.println("获取请求头===>" + request.getHeader("Accept"));
//getMethod()获取请求的方式 GET 或 POST
System.out.println("请求参数GET/POST===>" + request.getMethod());
}
}
如何获取请求参数
建立一个表单:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/servlet_request/parameter" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
兴趣爱好:<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="足球">足球
<input type="checkbox" name="hobby" value="排球">排球
<input type="checkbox" name="hobby" value="羽毛球">羽毛球<br>
<input type="submit" value="提交">
</form>
</body>
</html>
xml配置:
<servlet>
<servlet-name>ParameterServlet</servlet-name>
<servlet-class>com.example.servlet_request.ParameterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ParameterServlet</servlet-name>
<url-pattern>/parameter</url-pattern>
</servlet-mapping>
使用方法:
public class ParameterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求参数
System.out.println("用户:" + request.getParameter("username"));
System.out.println("密码:" + request.getParameter("password"));
System.out.println("兴趣爱好:" + request.getParameter("hobby")); //可以换成getParameterValues(), String[] hobbies = request.getParameterValues("hobby");
}
}
注意: 假如我们对爱好进行多选的时候就需要使用getParameterValues()获取请求的参数(多个值的时候使用)
请求的中文乱码解决
-
doGet请求的中文乱码解决
把Tomcat下面conf文件夹下的server.xml文件中:
<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" />
修改为:
<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
-
POST请求的中文乱码解决
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException { // 设置请求体的字符集为 UTF-8,从而解决 post 请求的中文乱码问题 req.setCharacterEncoding("UTF-8"); System.out.println("-------------doPost------------"); // 获取请求参数 String username = req.getParameter("username"); String password = req.getParameter("password"); String[] hobby = req.getParameterValues("hobby"); System.out.println("用户名:" + username); System.out.println("密码:" + password); System.out.println("兴趣爱好:" + Arrays.asList(hobby)); }
请求转发
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发
Forwardrequests代码:
public class Forwardrequests extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Forwardrequests(柜台1)中查看参数材料:"+username);
//给材料盖章并传到Forwardrequests2(柜台2)去查看
req.setAttribute("key","柜台1盖的章");
//问路:Forwardrequests2(柜台2)怎么走
/**
* /文件的工程目录,http://localhost:8080/工程目录
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/req2");
//走向Forwardrequests2(柜台2)
requestDispatcher.forward(req,resp);
}
}
Forwardrequests2代码:
public class Forwardrequests2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Forwardrequests(柜台2)中查看参数材料:"+username);
//查看是否有柜台1的盖章
Object key = req.getAttribute("key");
System.out.println("柜台1是否有章:"+key);
//处理自己的业务
System.out.println("柜台2处理自己的业务");
}
}
结果:
在Forwardrequests(柜台1)中查看参数材料:说的是的是
在Forwardrequests(柜台2)中查看参数材料:说的是的是
柜台1是否有章:柜台1盖的章
柜台2处理自己的业务
base标签作用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<base href="http://localhost:8080/servlet_request/a/b/c.html">
</head>
<body>
<a href="../../index.html">跳转到首页</a>
</body>
</html>
HttpServletResponse类作用
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传 递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息, 我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置(给客户端发送信息)
两个输入流的说明
字节流 | getOutputStream() | 常用于下载(传递二进制数据) |
字符流 | getWriter() | 常用于回传字符串(常用) |
注意:两个流同时只能使用一个。 使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
给客户端回传数据
给客户端回传字符串
public class HttpServletResponse1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.write("response's content!!!");
}
}
解决响应乱码问题
情景交际:
服务端(小明):我是个大帅比
客户端(小红):??????
很显然不赞同小明说的话并且表示疑问,因为没有进行贿赂(设置字符集)
方法一:
// 设置服务器字符集为 UTF-8
resp.setCharacterEncoding("UTF-8");
// 通过响应头,设置浏览器也使用 UTF-8 字符集
resp.setHeader("Content-Type", "text/html; charset=UTF-8")
方法二(推荐):
// 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html; charset=UTF-8");
请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求 重定向(因为之前的地址可能已经被废弃)
实现方法:
-
方案一:
//设置响应状态码302,表示重定向(搬迁) response.setStatus(302); //设置响应头,说明新地址位于哪里 response.setHeader("location","http://localhost:8080/servlet_request/response2");
-
方案二(推荐):
response.sendRedirect("http://localhost:8080/servlet_request/response2");