HTTP
-
概念: HTTP HyperText Transfer Protocol 超文本传输协议、
- 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
- 特点:
- 基于TCP/IP的高级协议
- 默认端口号:80
- 基于请求/响应模型的:一次请求对应一次响应
- 无状态的:每次请求之间相互独立,不能交互数据
- 历史版本:
- 1.0:每一次请求都会建立新的连接
- 1.1: 复用连接
-
请求消息数据格式
1、请求行- 请求方式 / 请求url 请求协议 / 版本
GET/day13_servlet/demo3 HTTP / 1.1 - 请求方式
HTTP协议中有七种请求方式,常用的有两种GET和POST-
GET
1.请求参数在请求行中,url里面
2.请求的url长度有限制
3.不太安全 -
POST
1.请求参数在请求体中
2.请求的url长度没有限制的
3.相对安全
-
- 请求方式 / 请求url 请求协议 / 版本
2、请求头
- 请求头名称:请求头值
- 常见的请求头:
1、 User-Agent:浏览器告诉服务器,我用什么版本的浏览器的信息
可以在服务器端获取该头信息,解决浏览器的兼容问题
2、 Referer:获取从哪里来的地址- 防盗链:
- 统计工作:
- 常见的请求头:
3、请求空行
空行 用于分割POST请求的请求头和请求体的
4、请求体(正文)
封装post请求消息的请求参数的
字符串格式:
GET/day13_servlet/demo3 HTTP / 1.1
Accept: text/html, application/xhtml+xml, application/xml; q=0.9, /; q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-Hans-CN, zh-Hans; q=0.5
Cache-Control: max-age=0
Connection: Keep-Alive
Host: localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363
- 响应消息数据格式
Request
-
request对象和response对象的原理
- request和response对象是由服务器创建的。我们来使用他们
- request对象获取请求信息,response对象设置响应消息
-
request对象继承体系结构:
ServletRequest --接口
| 继承
HttpServletRequest --接口
| 实现
org.apache.catalina.connector.RequestFacade 类(tomcat) -
request功能:
- 获取请求消息:
- 获取请求行数据:GET/day13_servlet/demo3 HTTP / 1.1
- 方法
-
获取请求方式:GET
String getMethod() -
(*)获取虚拟目录:/day13_servlet
getContextPath() -
获取Servlet路径:/demo3
get ServletPath() -
获取get方式的请求参数
String getQueryString() -
(*)获取请求URI:
String getRequestURI(); /day13_servlet/demo3
StringBuffer getRequestURL(); http://localhost/day13_servlet/demo3 -
获取协议及版本:HTTP/1.1
String getProtocol() -
获取客户机的IP地址:
String getRemoteAddr() -
注意点URL和URI的区别:
URI包含了URL和URN,URL是统一资源定位符,可以说是家庭地址,URN是统一资源标识符可以说是身份证号码。两者都可以唯一确定某一资源。
-
- 方法
- 获取请求行数据:GET/day13_servlet/demo3 HTTP / 1.1
- 获取请求消息:
举例获取请求行数据
package cn.itcast.web.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 演示Request对象获取请求方式
*/
@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
}
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException {
//获取请求方式:GET
String method = request.getMethod();
System.out.println(method);
//(*)获取虚拟目录:/dayshisan_war_exploded
String contextPath = request.getContextPath();
System.out.println(contextPath);
//获取Servlet路径:/requestDemo1
String servletPath = request.getServletPath();
System.out.println(servletPath);
//获取get方式的请求参数
String queryString = request.getQueryString();
System.out.println(queryString);
//(*)获取请求URI:
String requestURI = request.getRequestURI();// /dayshisan_war_exploded/requestDemo1
StringBuffer requestURL2 = request.getRequestURL();// http://localhost:8080/dayshisan_war_exploded/requestDemo1
System.out.println(requestURI);
System.out.println(requestURL2);
//获取协议及版本:HTTP/1.1
String protocol = request.getProtocol();
System.out.println(protocol);
//获取客户机的IP地址: 0:0:0:0:0:0:0:1
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
运行结果
GET
/dayshisan_war_exploded
/requestDemo1
null
/dayshisan_war_exploded/requestDemo1
http://localhost:8080/dayshisan_war_exploded/requestDemo1
HTTP/1.1
0:0:0:0:0:0:0:1
-
获取请求头数据
- 方法:
- String getHeader(String name); 通过请求头的名称获取请求头的值
- Enumeration<String> getHeaderNames(); 获取所有的请求头名称
Enumeration接口和迭代器有些类似,基本上被迭代器取代
- 方法:
-
获取请求体数据
请求体:只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数
方法:- 获取流对象:
BufferedReader getReader() 获取字符输入流,只能操作字符数据
ServletInputStream getInputStream() 获取字节输入流,可以操作所有类型数据 - 再从流对象中拿数据
- 获取流对象:
-
其它功能:
- 获取请求参数通用方式(GET和POST都可以)
- getParameter(String name); 根据参数名获取参数值
- String[] getParameterValues(String name); 根据参数名获取参数值的数组 这是当一个键对应多个值的时候用的
- Enumeration<String> getParameterNames(); 获取所有请求的参数名称
- Map<String,String[]> getParameterMap();获取所有参数的Map集合
- 中文乱码问题
- tomcat8.0往后,get方式不会产生乱码
- post方式会产生乱码,在doPost方法的第一行设置一下流的编码,改成和html页面的一样就行了,这里设置为utf-8
req.setCharacterEncoding(“utf-8”);
- 获取请求参数通用方式(GET和POST都可以)
代码举例:
这是对应的HTML页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/day14/requestDemo4" method="post"> <!--这儿的day14需要加上,从模块开始一直到所要连接的对象-->
<input type="text" placeholder="请输入用户名" name = "username"><br/>
<input type="text" placeholder="请输入密码" name="password"><br/>
<input type="checkbox" name="hobby" value="play ball">打球 <!--复选框checkbox-->
<input type="checkbox" name="hobby" value="play games">游戏
<input type="submit" value="注册">
</form>
</body>
</html>
这是Java后台写的doPost方法
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* 根据name获取单个value
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username " + username);
System.out.println("password " + password);
*/
/* 如果某个name有多个value,可以这样获取,获取到value的数组形式
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies
) {
System.out.println(hobby);
}
*/
/* 获取所有的name,再根据name用getParameter方法将每一个name的值获取到
这里有一个name对应多个value没有改,所以hobby选两个的话,这儿还是只会输出一个,
把方法改成获取数组类型就可以了
Enumeration<String> parameterNames = req.getParameterNames();
while(parameterNames.hasMoreElements()) {
String str = parameterNames.nextElement();
System.out.println(str);
String value = req.getParameter(str);
System.out.println(value);
System.out.println("--------------------------");
}
*/
/* 上述的修改后,可以将复选框中选中的两个值都输出出来
Enumeration<String> parameterNames = req.getParameterNames();
while(parameterNames.hasMoreElements()) {
String str = parameterNames.nextElement();
System.out.println(str);
String[] parameterValues = req.getParameterValues(str);
for (String parametervalue : parameterValues
) {
System.out.println(parametervalue);
}
System.out.println("--------------------------");
}
*/
/* 根据Map集合获取键值对,再用Set来迭代输出key和values
Map<String, String[]> parameterMap = req.getParameterMap();
Set<String> keyset = parameterMap.keySet();
for (String name : keyset
) {
System.out.println(name);
String [] values = parameterMap.get(name);
for (String value : values
) {
System.out.println(value);
}
System.out.println("---------------");
}
*/
}
-
请求转发:是一种发生在服务器内部的资源跳转方式
- 步骤:
- 第一步:通过request对象获取请求转发器对象:RequestDispatcher path = req.getRequestDispatcher(“要跳转到的路径”);
- 第二步:使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response);
- 特点:
- 浏览器地址栏不发生变化
- 只能转发到当前服务器内部资源中
- 转发是一次请求
- 步骤:
-
共享数据
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
- 方法:
- void setAttribute(String name,Object obj);存储数据
- Object getAttribute(String name); 通过键获取值
- void removeAttribute(String name); 通过键移除键值对
- 注意:要转发前存储数据
-
获取ServletContext
ServletContext getServletContext()
这个方法在之后细讲
本文深入解析HTTP协议的概念、特点和历史版本,详细介绍了请求与响应消息的数据格式,包括请求行、请求头、请求体以及响应消息的构成。同时,探讨了Servlet中request对象的功能和使用方法,如获取请求信息和请求参数。
1837

被折叠的 条评论
为什么被折叠?



