# `day032` `Request`
> 作者: 张大鹏
## 001.`Servlet`体系结构
```
Servlet -- 接口
--->>>
GenericServlet -- 抽象类
--->>>
HttpServlet -- 抽象类
```
> `GenericServlet`:将`Servlet`接口中其他的方法做了默认空实现,只将service()方法作为抽象
>
> 将来定义`Servlet`类时,可以继承`GenericServlet`,实现service()方法即可
> `HttpServlet`:对`http`协议的一种封装,简化操作
- 1.定义类继承`HttpServlet`
- 2.复写`doGet/doPost`方法
## 002.`Servlet`相关配置
1.一个`Servlet`可以定义多个访问路径
- `@WebServlet({"/d4","/dd4","/ddd4"})`
2.路径定义规则
- 1.`/xxx`:路径匹配
- 2.`/xxx/xxx`:多层路径,目录结构
- 3.`*.do`:扩展名匹配
## 003.`HTTP`
> 概念:Hyper Text Transfer Protocol 超文本传输协议
1.传输协议:定义了,客户端和服务器端通信时,发送数据的格式
2.特点:
1. 基于TCP/IP的高级协议
2. 默认端口号:80
3. 基于请求/响应模型的:一次请求对应一次响应
4. 无状态的:每次请求之间相互独立,不能交互数据
3.历史版本
1.0:每一次请求响应都会建立新的连接
1.1:复用连接
## 004.请求消息数据格式
1.请求行
2.请求头
3.请求空行
4.请求体
## 005.请求方式
HTTP协议有7中请求方式,常用的有2种
- 1.GET
- 1.请求参数在请求行中,在`url`后。
- 2.请求的`url`长度有限制的
- 3.不太安全
- 2.POST
- 1.请求参数在请求体中
- 2.请求的`url`长度没有限制的
- 3.相对安全
## 006.常用请求头
请求头:客户端浏览器告诉服务器一些信息
- 1.`User-Agent`:浏览器告诉服务器,我访问你使用的浏览器版本信息
- 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
- 2.`Referer:http://localhost/login.html`
- 告诉服务器,我(当前请求)从哪里来?
- 防盗链
- 数据统计
## 007.Request
request和response对象是由服务器创建的。我们来使用它们
request对象是来获取请求消息,response对象是来设置响应消息
## 008.获取请求行数据
1.获取请求方式 :GET `String getMethod() `
2.获取虚拟目录:`String getContextPath()`
3.获取`Servlet`路径: `String getServletPath()`
4.获取get方式请求参数: `String getQueryString()`
5.获取请求URI: `String getRequestURI()` `StringBuffer getRequestURL() `
- `URL`:统一资源定位符,绝对路径
- `URI`:统一资源标识符,相对路径
6.获取协议及版本: `String getProtocol()`
7.获取客户机的`IP`地址: `String getRemoteAddr()`
```java
package com.lxgzhw.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;
import java.io.IOException;
/*
获取请求行数据
*/
@WebServlet("/demo01")
public class Demo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求方法 getMethod()
String method = req.getMethod();
System.out.println("请求方式:" + method);
System.out.println("-------------------------------");
//获取虚拟根目录
String contextPath = req.getContextPath();
System.out.println("虚拟根目录:" + contextPath);
System.out.println("-------------------------------");
//获取Servlet路径
String servletPath = req.getServletPath();
System.out.println("Servlet路径:" + servletPath);
System.out.println("-------------------------------");
//获取get请求参数
String queryString = req.getQueryString();
System.out.println("请求参数:" + queryString);
System.out.println("-------------------------------");
//获取URI
String requestURI = req.getRequestURI();
System.out.println("统一资源标识符:" + requestURI);
System.out.println("-------------------------------");
//获取协议及版本
String protocol = req.getProtocol();
System.out.println("协议及版本:" + protocol);
System.out.println("-------------------------------");
//获取客户机的ip地址
String remoteAddr = req.getRemoteAddr();
System.out.println("用户ip地址:" + remoteAddr);
System.out.println("-------------------------------");
}
}
```
## 009.获取请求头数据
`String getHeader(String name)`:通过请求头的名称获取请求头的值
`Enumeration<String> getHeaderNames()`:获取所有的请求头名称
```java
package com.lxgzhw.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;
import java.io.IOException;
import java.util.Enumeration;
/*
获取请求头数据
*/
@WebServlet("/demo02")
public class Demo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取所有的请求头名称
Enumeration<String> headerNames = req.getHeaderNames();
//根据名称获取值
while (headerNames.hasMoreElements()) {
String s = headerNames.nextElement();
String header = req.getHeader(s);
System.out.println(s + ":" + header);
}
}
}
```
## 010.获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
步骤:
- 1.获取流对象
- `BufferedReader getReader():获取字符输入流,只能操作字符数据`
- `ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据`
- 2.再从流对象中拿数据
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>演示post方式提交</h1>
<form action="/demo05" method="post">
<input type="text" name="username">
<input type="submit" value="确认">
</form>
</body>
</html>
```
```java
package com.lxgzhw.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;
import java.io.BufferedReader;
import java.io.IOException;
@WebServlet("/demo05")
public class Demo05 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取字符流
BufferedReader reader = req.getReader();
//2.读取数据
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
```
## 011.通用获取方式
1.` String getParameter(String name)`:根据参数名称获取参数值,可以获取get参数
2.` String[] getParameterValues(String name)`:根据参数名称获取参数值的数组
3.`Enumeration<String> getParameterNames()`:获取所有请求的参数名称
4.`Map<String,String[]> getParameterMap()`:获取所有参数的map集合
```java
package com.lxgzhw.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;
import java.io.IOException;
import java.util.Map;
@WebServlet("/demo06")
public class Demo06 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取参�