HTTP——基本概念、请求消息、Request
HTTP
概念
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准
传输协议:定义了客户端和服务端通信时,发送数据的格式
HTTP是一个基于TCP/IP通信协议来传递数据
HTTP的默认端口为80
基于请求/响应模型:一次请求对应一次响应
HTTP是一种无状态协议,每次请求之间相互独立,无法交互数据
请求消息数据格式
请求行
请求方式 请求URL 请求协议/版本
○ 请求方式
HTTP标准有9种请求方式
方法 | 描述 |
---|---|
GET | 请求指定的页面信息,并返回实体主体 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
POST | 向指定资源提交数据进行处理请求,数据被包含在请求体中,POST 请求可能会导致新的资源的建立和/或已有资源的修改 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容 |
DELETE | 请求服务器删除指定的页面 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器 |
OPTIONS | 允许客户端查看服务器的性能 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 |
GET与POST请求的区别
GET:请求参数在==请求行==中(拼接在URL之后),请求的URL长度有限制
POST:请求参数在==请求体==中,请求的URL长度没有限制
请求头
请求头名称:请求头值
○ 常见的请求头
- User-Agent:访问服务器使用的浏览器版本信息,可获取该头信息来解决浏览器兼容问题
- Accept:浏览器可接收的文件类型
- Accept-Language:浏览器可接收的语言
- Accept-Encoding:浏览器可支持的编码类型
- Referer:告知服务器请求的来源URL,可用来做统计工作和防止盗链
请求空行
空行,分隔请求头和请求体
请求体
封装POST请求消息的请求参数
Request
继承体系结构
功能
获取请求消息数据
(1). 获取请求行数据
方法 | 描述 |
---|---|
String getMethod() | 获取请求方式 |
String getContextPath() | 获取虚拟目录 |
String getServletPath() | 获取Servlet路径 |
String getQueryString() | 获取get方式请求参数 |
String getRequestURI() | 获取请求URI |
String getProtocol() | 获取协议及版本 |
String getRomoteAddr() | 获取客户机IP地址 |
@WebServlet("/requestDemo")
public class RequestDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求方式
String method = request.getMethod();
System.out.println(method);
// 获取虚拟目录
String contextPath = request.getContextPath();
System.out.println(contextPath);
// 获取Servlet路径
String servletPath = request.getServletPath();
System.out.println(servletPath);
// 获取get请求方式参数
String queryString = request.getQueryString();
System.out.println(queryString);
// 获取请求URI
String requestURI = request.getRequestURI();
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURI);
System.out.println(requestURL);
// 获取协议及版本
String protocol = request.getProtocol();
System.out.println(protocol);
// 获取客户机IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
(2). 获取请求头数据
方法 | 描述 |
---|---|
String getHeader(String name) | 根据请求头名称获取请求头的值 |
Enumeration< String > getHeaderNames() | 获取所有的请求头名称 |
@WebServlet("/requestDemo")
public class requestDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取所有请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
// 遍历
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
// 获取请求头的值
String value = request.getHeader(name);
System.out.println(name + "===" + value);
}
}
}
(3). 获取请求体数据
只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数
方法 | 描述 |
---|---|
BufferedReader getReader() | 获取字符输入流,只能操作字符数据 |
ServletInputStream getInputStream() | 获取字节输入流,可以操作所有类型的数据 |
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取字符流
BufferedReader reader = request.getReader();
// 读取数据
String line = null;
while ((line = reader.readLine()) != null){
System.out.println(line);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
获取请求参数通用方式
无论是get还是post请求方式都可以使用以下方法获取请求参数,由于方式通用,所以不必在doGet和doPost中重复写相同的代码
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 通用方式代码
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
方法
① String getParameter(String name):根据参数名称获取参数值
String name = request.getParameter("name");
System.out.println(name);
② String[] getParameterValues(String name):根据参数名称获取参数值的数组
String[] checks = request.getParameterValues("check");
for (String check : checks) {
System.out.println(check);
}
③ Enumeration< String > getParameterNames():获取所有的请求参数名称
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String s = parameterNames.nextElement();
System.out.println(s);
}
④ Map< String,String[] > getParameterMap():获取所有参数的Map集合
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for (String key : keySet) {
// 根据key获取value
String[] values = parameterMap.get(key);
for (String v : values) {
System.out.println(v);
}
}
完整代码
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("post");
System.out.println("------------");
// 根据参数名获取参数值
String name = request.getParameter("name");
System.out.println(name);
// 根据参数名获取多选参数值
String[] checks = request.getParameterValues("check");
for (String check : checks) {
System.out.println(check);
}
// 获取所有请求的参数名称
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String s = parameterNames.nextElement();
System.out.println(s);
}
// 获取所有参数的Map集合
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for (String key : keySet) {
// 根据key获取value
String[] values = parameterMap.get(key);
for (String v : values) {
System.out.println(v);
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("get");
System.out.println("------------");
this.doPost(request,response);
}
}
获取请求参数中的中文乱码问题
tomcat8 已经解决了get方式的中文乱码问题,但post方式仍会出现乱码问题
可以通过setCharacterEncoding()方法在==获取参数之前==将Request编码更改为 utf-8
request.setCharacterEncoding("utf-8");
请求转发
一种在服务器内部的资源跳转方式
请求转发步骤
- 通过Request对象获取请求转发器对象
RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象的forward()方法来进行转发
void forward(ServletRequest request, ServletResponse response)
示例
demo4代码
@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("this is demo 4");
// 转发到demo5
request.getRequestDispatcher("RequestDemo5").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
demo5代码
@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("this is demo 5");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
访问RequestDemo4控制台输出为
this is demo 4
this is demo 5
请求转发特点
- 浏览器地址栏路径不会发生变化
- 只能转发到当前服务器内部资源中,不能转发到外部资源
- 转发是一次请求
共享数据
域对象
一个具有作用范围的对象,可以在范围内共享数据
Request域
代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法
方法 | 描述 |
---|---|
void setAttribute(String name, Object o) | 存储数据 |
Object getAttribute(String name) | 通过键来获取值 |
void removeAttribute(String name) | 通过键移除键值对 |
demo4代码
@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("this is demo 4");
// 存储数据到Request域中
request.setAttribute("name","name1");
// 转发到demo5
request.getRequestDispatcher("RequestDemo5").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
demo5代码
@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取并输出Request域中的数据
Object name = request.getAttribute("name");
System.out.println(name);
System.out.println("this is demo 5");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
访问RequestDemo4后控制台输出
this is demo 4
name1
this is demo 5
获取ServletContext
○ ServletContext getServletContext()
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
System.out.println(servletContext);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
输出结果
org.apache.catalina.core.ApplicationContextFacade@158ac881
评论