Http - Request
HTTP概述
概念
- HTTP: Hyper Text Transfer Protocol 超文本传输协议
- 传输协议: 定义了客户端和服务器端通信时, 发送数据的格式
特点:
1. 基于TCP/IP的高级协议(三次握手, 安全)
2. 默认端口号: 80
3. 基于请求/ 响应模型的, 一次请求对应一次响应
4. 无状态的协议, 每次请求之间相互独立, 不能交互数据
历史版本
- 1.0: 每一次请求响应都会建立新的连接
1.1: 复用连接, 一次连接请求结束后会等待一会, 如果有新的数据发送, 就默认使用之前的连接
Request
请求消息数据格式
1. 请求行
请求方式 请求url 请求协议/版本
GET localhost/tomcat05/login.html HTTP/1.1
请求方式:
HTTP协议有7种请求方式, 常用的有2种
GET
请求参数在请求行中(在url后)
请求的url长度有限制
不太安全, 你被别人直接看到
POST
请求参数在请求体中(浏览器-> F12 -> 网络 -> POST - >参数)
请求的url长度没有限制
相对安全
2. 请求头
格式
请求头名称: 请求头值
常见的请求头
User-Agent: 浏览器告诉服务器, 访问服务器使用的浏览器版本信息
可以在服务器端获取该头的信息, 解决浏览器兼容性问题
Accept: 可以支持的信息格式
Referer: 告诉服务器, 当前请求从哪里来, 从哪个网址点击超链接访问到这里
作用:
防止盗链
统计工作
3. 请求空行
一个空行, 用来分隔请求头和请求体
4. 请求体
封装POST请求消息的请求参数
请求头的字符串格式:
GET localhost/login.html HTTP/1.1
Host: localhost
User-Agent: Mozila/5.0(Windows NT 10.0; Win64;×64; rv:76.0) Gecko/20100101 Firefox/76.0
Accept: image/webp,*/*
Accept-Language: zh-CN, zh;q=0.8, Zh-TW;q=0.7, zh-HK;q=0.5, en-US;q=0.3, en;q=0.2
Accept-Encoding: gzip, deflate Connection: keep-alive Cookie: Idea-6cb7b915=0e17dc10-ba29-459a-88bc-07379a725d88
Request对象
1. Request对象和Response对象的原理
-
request和response对象是由服务器创建的, 我们来使用它们
-
request对象是来获取请求消息, response对象来设置响应消息
-
请求消息过程
1. 浏览器发出请求 2. Tomcat服务器根据请求url中的资源路径, 创建对应的Servlet对象 3. Tomcat服务器, 会创建request和response对象, request对象中封装请求消息数据 4. Tomcat将request和response两个对象传递给service方法, 并且调用service方法 5. 程序员可以通过request对象获取请求消息数据, 通过response对象设置响应消息数据 6. 服务器在给浏览器做出响应前, 会从response对象中拿程序员设置的响应消息数据
2. request对象继承体系结构
ServletRequest接口 -> 继承
HeetServletRequest接口 ->实现
org.apache.catalina.connector.RequestFacade类 (Tomcat)
3. request功能
相关API: https://tool.oschina.net/apidocs/apidoc?api=javaEE6
javax.servlet.http.HttpServletRequest;
1. 获取请求行数据
请求行: GET localhost/tomcat05/demo03?name=zhangsan HTTP/1.1
其中 tomcat05为虚拟目录, demo03为Servlet所在路径
1. 方法: 获取请求方式: GET
String getMethod()
2. 获取虚拟目录: /tomcat05 (重要)
getContextPath()
3. 获取Servlet路径: /demo01
String getServletPath()
4. 获取get方式请求参数: name=zhangsan
String getQueryString()
5. 获取请求URI: /tomcat05/demo01 (重要)
String getRequestURI(): 返回/tomcat/demo01
StringBuffer getRequestURL(): 返回http://localhost/tomcat03/demo01
URL: 统一资源定位符
URI: 统一资源标识符
6. 获取协议及版本: HTTP/1.1
String getProtocol()
7. 获取客户机的IP地址:
String getRemoteAddr()
重要方法: getContextPath(), getURI()
2. 获取请求头数据
方法
String getHeader(String name): 通过请求头的名称获取请求头的值
(重要) req.getHeader("referer"): 返回用户点击超链接到达此页面的超链接所在的url
(用户点击a.html中的超链接进入该页面, 则返回a.html所在的url)
Enumeration<String> getHeaderNames(): 获取所有的请求头名称
3. 获取请求体数据
请求体: 只有POST请求方式才有请求体, 在请求体中封装了POST请求的请求参数
步骤
1. 获取流对象
BufferedReader getReader(): 获取字符输入流, 只能操作字符输入
ServletInputStream getInputStream(): 获取字节输入流, 可以操作所有类型数据
2. 从流对象中拿数据
3. 其他功能
1. 获取请求参数通用方式(兼容GET和POST)
1. String getParameter(String name)
根据参数名称获取参数值
例如: username=zhangsan&password=123
getParameter("username") 返回 "zhangsan""
2. String[ ] getParameterValues(String name)
根据参数名称获取参数值的数组
例如: hobby=jogging&hobby=game
getParameterValues("hobby") 返回hobby值的数组
用于复选框表单的接收
3. Enumeration<String> getParameterNames()
获取所有请求的参数名称
4. Map<String, String[ ]> getParamaterMap()
获取所有请求参数的map集合
(常用)
中文乱码问题
GET方法: Tomcat8以后的版本已经解决了中文乱码问题
POST方法: 会乱码
解决:
设置流的编码
request.setCharacterEncoding("utf-8");
建议获取参数前加入此代码
2. 请求转发
定义: 一种在服务器内部的资源跳转方式
1. 步骤:
1. 通过request对象获取请求转发器对象
RquestDispatcher getRequestDispatcher(String path)
2. 使用Requestdispatcher 对象转发
void forward(ServletRequest req, ServletResponse resp)
path为虚拟路径下的Servlet路径(不加虚拟路径)
例如虚拟路径为/tomcat, Servlet路径为/requestdemo09
req.getRequestDispatcher("/requestdemo09").forward(req, resp);
2. 特点 :
1. 浏览器地址栏路径不发生变化
2. 只能转发到当前Tomcat服务器部署的资源内部, 不能访问外部url
3. 转发是一次请求, 只发送了一个request请求, 多个资源之间使用的是同一个请求
3. 共享数据
域对象: 一个有作用范围的对象, 可以在范围内共享数据
request域: 代表一次请求的范围, 一般英语请求转发的多个资源中共享数据
方法:
1. void setAttribute(String name, Object obj): 存储数据
2. Object getAttrubute(String name): 通过键获取值
3. void removeAttribute(String name): 通过键移除键值对
在一个Servlet a中调用setAttribute()方法, 传入数据
通过请求转发跳转到另一个Servlet b中
在Servlet b中调用getAttribute()获取Servlet a传入的数据
达到数据共享的目的
-
获取ServletContext
ServletContext getServletContext();
HTML文件中form表单action路径的写法
虚拟目录 + Servlet的资源路径
BeanUtils工具类, 简化数据封装
用于封装JavaBean的
-
JavaBean概念: 标准的Java类
- 要求
- 类必须被public修饰
- 必须提供空参的构造器
- 成员变量必须使用provate修饰
- 提供公公的setter和getter方法
- 功能: 封装数据
- 要求
-
概念
- 成员变量:
例如: private String name; - 属性: setter和getter方法截取后的产物, 即setXxx中截取set后的字符串, 首字母改为小写
例如: getUsername() -> Username -> username
大多数时候, 成员变量和属性是一致的, 但getter和setter方法的名称可能与成员变量名不同
- 成员变量:
-
方法
- void setProperty(Object bean, String name, Object value)//传入的name是属性, 不是成员变量名 (了解)
- String getProperty(Object bean, String name) (了解)
- void populate(Object bean, Map properties)
将map集合的键值对信息, 封装到对应的avaBean对象中, 与req.getParameterMap()配合使用
实例:
//1. 设置编码
req.setCharacterEncoding("UTF-8");
//2. 获取所有请求参数
Map<String, String[]> parameterMap = req.getParameterMap();
//3. 创建User对象
User loginUser = new User();
//3.2 使用BeanUtils封装
try {
BeanUtils.populate(loginUser, parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}