前言:HTTP是基于TCP/IP的高级协议的超文本传输协议,定义了客户端和服务器端通信时,发送数据的格式。它的默认端口号是80,具有一次请求对应一次响应(基于请求响应模型)和每次请求之间相互独立,不能交互数据(无状态的)的特点。
一.请求数据格式
1.请求行:请求方式(POST或GET) 请求路径 请求协议/版本号
请求方式 | 请求参数 | url长度 | 安全性 |
POST | 请求参数在请求体中 | 没有限制 | 相对安全 |
GET | 请求参数在请求行中 | 有限制 | 不太安全 |
2.请求头:请求头名称:请求头值
常用请求头 | 存储信息 | 作用场景 |
User-Agent | 浏览器版本 | 可以在服务器端获取,用于解决浏览器的兼容问题 |
Referer | 请求来自于哪里 | 防盗链,统计工作 |
3.请求空行:空行,用作分割
4.请求体:
请求方式 | 请求体 |
POST | 请求参数 |
GET | 无请求体 |
二.Request对象
1.Request对象原理如图所示(Response对象同理)
补充:Request对象是由服务器创建,我们使用Request对象来获取消息。
2.Request的体系结构
RequestFacade(类)
实现
HttpServletRequest(接口)
继承
ServletRequest(接口)
3.Request对象功能 (基于Servlet进行演示)
1.获取信息功能 (标*较为重要)
- 获取请求行数据
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
public class ServletDome1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**获取请求行数据*/
//获取请求方式
String method = req.getMethod();
//获取请求虚拟目录 *
String contextPath = req.getContextPath();
//获取Servlet路径
String servletPath = req.getServletPath();
//获取GET请求参数
String queryString = req.getQueryString();
//获取请求的URI *(统一资源标识符,URI代表的范围大)
String requestURI = req.getRequestURI();
//获取请求的URL(统一资源定位符)
StringBuffer requestURL = req.getRequestURL();
//获取协议及版本
String protocol = req.getProtocol();
//获取客户机的IP地址
String remoteAddr = req.getRemoteAddr();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
- 获取请求头数据
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
public class ServletDome1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**获取请求头数据*/
//通过请求头的名称获取请求头的值 (*)
String header = req.getHeader("User-Agent");
//获取所有请求头的名称(可以当作迭代器使用)
Enumeration<String> headerNames = req.getHeaderNames();
//获取所有请求头数据
while (headerNames.hasMoreElements()){
String value = req.getHeader(headerNames.nextElement());
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
- 获取请求体数据(仅限POST请求)
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
public class ServletDome1 extends HttpServlet {
/**获取请求体数据(只有post请求才有)*/
//获取流对象(字节流或者字符流)
ServletInputStream inputStream = req.getInputStream();
BufferedReader reader = req.getReader();
//再从流对象里面拿数据
String line = null;
while ((line = reader.readLine()) !=null){
System.out.println(line);
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
- request公用方法(较为重要)
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
public class ServletDome2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**获取请求参数通用根据参数名称获取数值(无论post还是get都可以)*/
//根据名字获取值 (*)
String parameter = req.getParameter("");
//根据名字获取数组
String[] parameterValues = req.getParameterValues("");
//获取所有参数的名字
Enumeration<String> parameterNames = req.getParameterNames();
//获取所有参数(上面API组合)
while (parameterNames.hasMoreElements()){
String nextElement = parameterNames.nextElement();
String parameter1 = req.getParameter(nextElement);
}
//获取所有参数的名字和值到一个map集合中 (*)
Map<String, String[]> parameterMap = req.getParameterMap();
Set<String> strings = parameterMap.keySet();
for (String string : strings) {
String[] strings1 = parameterMap.get(string);
for (String s : strings1) {
System.out.println(s);
}
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
2.解决中文乱码问题
前言: 在tomcat8版本以上,GET请求的乱码问题被tomcat解决,但POST依然存在乱码问题。
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDome3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**设置req的编码形式*/
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
System.out.println(username);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
这里小编设置utf-8为例(设置和自己浏览器编码一样即可)。
3.请求转发
1. 请求转发概念:一种在服务器内部的资源跳转方式(如图所示)
2. 请求转发的特点
- 浏览器地址栏的路径不发生变化
- 只能转发到当前服务器中
- 转发是一次请求
3.请求转发的实现
- Aservlet
package com.lsl.Servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过request对象获取请求转发对象
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/BServlet");
//利用转发对象进行转发
requestDispatcher.forward(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
- Bservlet
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("由Aservlet转发的请求访问该Servlet");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
4. 数据共享
补充:
- 域对象:一次有作用范围的对象,可以在作用范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发多个资源中共享数据
1.数据共享API
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 共享数据
* 域对象:一次有作用范围的对象,可以在范围内共享数据
* request域:代表一次请求的范围,一般用于请求转发多个资源中共享数据
**/
public class ServletDome6 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**存储数据*/
req.setAttribute("username",000);
/**通过键获取值*/
req.getAttribute("username");
/**通过键移除键值对*/
req.removeAttribute("username");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
2.数据共享实现
- Aservlet
package com.lsl.Servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**转发之前存入数据,达到共享数据的目的*/
req.setAttribute("username",000);
//通过request对象获取请求转发对象
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/BServlet");
//利用转发对象进行转发
requestDispatcher.forward(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
- Bservlet
package com.lsl.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("由Aservlet转发的请求访问该Servlet");
/**获取Aservlet中存入的数据*/
System.out.println(req.getAttribute("username"));
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
到这里小编讲解完了HTTP(Request)篇,欢迎一起探讨学习。