1.HTTP协议
概念:Hyber Text Transfer Protocal 超文本传输协议
定义了客户端和服务器端通信时,发送数据的格式
特点:
- 基于TCP/IP的高级协议
- 默认端口号80
- 基于请求/响应模型:一次请求对应一次响应
- 无状态:每次请求之间相互独立,不能交互数据
历史版本
- 1.0版本:每次请求都会重新建立连接
- 1.1版本:复用连接
2.HTTP请求消息数据格式
请求行
请求方式 请求url 请求协议/版本
- GET
- 请求参数在请求行中,在url后
- 请求的url长度有限制
- POST
- 请求参数在请求体中
- 请求的url长度没有限制
- GET
请求头:请求头名称:请求头值,键值对格式
- Host:请求的主机
- User-Agent:浏览器告诉服务器浏览器版本信息。可以在服务器端获取该头的信息,解决浏览器的兼容性问题
- Accept:本浏览器可以接受的资源格式
- Accept-Lanuage:支持语言环境
- Accept-Encoding:压缩格式
- Referer:告诉服务器,当前请求从哪里来。
- 防盗链
- 统计工作
请求空行
空行,分割POST请求消息的请求头和请求体
请求体(正文)
- 封装POST请求消息的请求参数
3.请求响应原理
- tomcat服务器会根据请求url中的资源路径,创建对应的servlet对象。
- tomcat服务器会创建request和response对象,request对象中封装请求消息数据。
- tomcat将request和response两个对象传递给service方法,并且调用service
- 在service方法中可以通过request对象获取请求消息数据,通过response对象设置响应消息数据。
- 服务器在给浏览器做出响应之前,会从response对象中取设置的响应消息数据。
4.request对象
4.1request对象继承体系结构
- ServletRequest:接口
- HttpServletRequest:接口,继承ServletRequest
- org.apache.catalina.connector.RequestFacade:实现HttpServletRequest接口
4.2request功能
获取请求消息数据
获取请求行数据
eg. GET /test/demo?name=zhangsan HTTP/1.1
获取请求方式:String getMethod(); GET
获取虚拟目录:String getContextPath(); /test
获取Servlet路径:String getServletPath(); /demo
获取GET方式请求参数:String getQueryString(); name=zhangsan
获取请求URI(统一资源标识符):String getRequestURI(); /test/demo
获取请求URL(统一资源定位符):String getRequestURL(); http://localhost:8080/test/demo
获取请求协议:String getProtocol: HTTP/1.1
获取客户机的IP地址:String getRemoteAddr();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class requestdemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(request.getMethod());
System.out.println(request.getContextPath());
System.out.println(request.getServletPath());
System.out.println(request.getQueryString());
System.out.println(request.getRequestURI());
System.out.println(request.getRequestURL());
System.out.println(request.getProtocol());
System.out.println(request.getRemoteAddr());
}
}
/*输入的链接:http://localhost:8080/test/requestdemo1?name=zhangsan
GET
/test
/requestdemo1
name=zhangsan
/test/requestdemo1
http://localhost:8080/test/requestdemo1
HTTP/1.1
0:0:0:0:0:0:0:1
*/- 获取请求头数据
- String getHeader(String name):通过请求头的名称获取请求头的值
- Enumeration < String >getHeaderNames():获取所有的请求头名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class requestdemo2 extends HttpServlet {
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);
}
//简单防盗链
String referer = request.getHeader("referer");
System.out.println(referer);
// http://localhost/test/requestdemo2
if (referer!=null){
if (referer.contains("/test")){
System.out.println("播放");
}else{
System.out.println("不播放");
}
}
}
}
获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
步骤
(1) 获取流对象,字节流或字符流
- BufferedReader getReader():获取字符输入流,只能操作字符数据
- ServletInputStream():获取字节输入流,可以操作所有数据类型
1
2
3
4
5
6
7
8
9protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体
BufferedReader br = request.getReader();
//读取数据
String line = null;
while ((line= br.readLine())!=null){
System.out.println(line);
}
}(2) 从流对象中拿数据
获取请求参数通用方式
String getParameter(String name):根据参数名称获取参数值 username=hxx
String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=yy
Enumeration< String >getParameterNames():获取所有请求的参数名称
Map< String,String[] > getParameterMap():获取所有参数的map集合
中文乱码问题:
get方式:tomcat8已经将get方式乱码问题解决
post方式:会乱码,需要在获取参数前设置编码 request.setCharacterEncoding(“utf-8”);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置流的编码,要和所对应的页面格式相同
request.setCharacterEncoding("utf-8");
//POST 请求参数
//根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println(username);
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
//获取所有请求参数的名称
Enumeration<String> parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()){
//参数名字
String name = parameterNames.nextElement();
//根据参数名字获取参数值
String parameter = request.getParameter(name);
System.out.println(name+"---->"+parameter);
}
//获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
//获取键值
Set<String> keySet = parameterMap.keySet();
//根据键值获取值
for (String name : keySet) {
String[] values = parameterMap.get(name);
for (String value : values) {
System.out.println(value);
}
}
}请求转发:一种在服务器内部的资源跳转方式
通过request对象获取请求转发器对象
RequestDispatcher getRequestDispacher(String path):参数为转发资源的路径
使用RequestDispatcher对象进行转发
forward(ServletRequest request, ServletResponse response)
1
request.getRequestDispatcher("/requestdemo5").forward(request,response);
- 特点
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中
- 转发是一次请求
共享数据
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求,一般用于请求转发的多个资源中共享数据
- 方法
- setAttribute(String name,Object obj):存储数据
- Object setAttribute(String name):通过键获取值
- removeAttribute(String name):通过键移除键值对
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class requestdemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置request域
request.setAttribute("msg","hxx");
//转发到demo5
request.getRequestDispatcher("/requestdemo5").forward(request,response);
}
}
public class requestdemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo5--------");
//获取request域值
Object msg = request.getAttribute("msg");
System.out.println(msg);
}
}
获取ServletContext对象
- servletContext getServletContext()