1、原理
第一步:用户访问url,浏览器向服务器发出请求,请求携带着请求消息数据;
第二步:Tomcat服务器会根据请求url中的资源路径,创建对应的Servlet对象;
第三步:Tomcat服务器创建request对象和seponse对象,request对象封装着请求消息数据;
第四步:Tomcat服务器将request对象和seponse对象传递给service方法,并调用service方法;
第五步:我们(程序员)可以在service方法中通过request对象获取请求消息数据,通过response对象设置响应消息数据;
第六步:Tomcat服务器从response对象中获取响应消息数据,返回给浏览器;
备注:
1、request对象和response对象是由服务器创建的,我们(程序员)来使用它;
2、request对象用户获取请求消息数据,response对象用于设置响应消息数据;
2、继承体系
二、获取请求数据
1、获取请求行数据
GET:/web/index?name=zhangsan HTTP/1.1
方法:
①获取请求方式:GET
String getMethod();
②(重要)获取虚拟目录:/index
String getContextPath();
③获取Servlet路径:/web
String getServletPath();
④获取GET方式请求参数:name=zhangsan
String getQueryString();
⑤(重要)获取请求URI:/web/index
String getRequestURI();
/web/index
StringBuffer getRequestURL();
http://localhost/web/index
URL:统一资源定位符;
URI:统一资源标识符;
⑥获取协议及版本:HTTP/1.1
String getProtocol();
⑦获取客户机的IP地址:
String getRemoteAddr();
2、获取请求头数据
获取单个请求头数据(常用):
String getHeader(String var1);
获取所有请求头数据:
Enumeration<String> getHeaderNames();
Enumeration可以当作是一个迭代器;
代码演示:
package com.zibo.servlet;
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("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("doGet……");
//获取所有请求头
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
String value = req.getHeader(name);
System.out.println(name+"--------"+value);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("doPost……");
}
}
运行结果:
doGet……
host--------localhost:8080
connection--------keep-alive
upgrade-insecure-requests--------1
user-agent--------Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
accept--------text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-encoding--------gzip, deflate, br
accept-language--------zh-CN,zh;q=0.9
cookie--------__guid=111872281.1266672611192455200.1567215662252.909; _ga=GA1.1.492873635.1567215662; JSESSIONID=22205AFD55EE3DA1BC8CD4F8307C9707; monitor_count=4
3、获取请求体数据
明确:
只有POST请求才有请求体,在请求体中封装了请求参数;
步骤:
第一步:获取流对象;
BufferedReader getReader():获取字符输入流,只能操作字符数据;
ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据;
第二步:从流对象中拿数据;
代码演示getReader():
package com.zibo.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
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("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("doGet……");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("doPost……");
BufferedReader reader = req.getReader();
while (true) {
String s = reader.readLine();
if(s!=null){
System.out.println(s);
}else {
break;
}
}
}
}
代码演示getInputStream():
package com.zibo.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
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("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("doGet……");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("doPost……");
ServletInputStream inputStream = req.getInputStream();
byte[] bytes = new byte[64];
while (true) {
int read = inputStream.read(bytes);
if(read!=-1){
System.out.println(new String(bytes));
}else {
break;
}
}
}
}
运行结果:
doPost……
username=%E6%94%BE%E6%9D%BE%E6%94%BE%E6%9D%BE
4、获取请求参数通用方式(重要)
(常用)String getParameter(String var1):根据参数名称获取参数值;
String[] getParameterValues(String var1):根据参数名称获取参数值的数组;
Enumeration<String> getParameterNames():返回所有参数名称;
(常用)Map<String, String[]> getParameterMap():获取所有参数的Map集合;
中文乱码问题:
GET方式:Tomcat8已经将中文乱码的问题解决了;
POST方式:加一行代码即可(设置编码)
req.setCharacterEncoding("utf-8");
5、请求转发
一种服务器资源在服务器内部的资源跳转方式;
步骤:
第一步:通过request对象获取请求转发器对象
RequestDispatcher getRequestDispatcher(String path);
path:转发到的资源路径
第二步:使用RequestDispatcher对象进行转发
void forward(ServletRequest var1, ServletResponse var2)
特点:
①浏览器地址栏路径不发生变化;
②只能转发到服务器内部资源;
③转发是一次请求;
6、共享数据
域对象:
一个有作用范围的对象,可以在范围内共享数据;
request域:
代表一次请求的范围,一般用于请求转发的多个资源中共享数据;
方法:
①存储数据;
void setAttribute(String name, Object obj);
②通过键获取值;
Object getAttribute(String name);
③通过键移除键值对;
void removeAttribute(String name);
7、获取ServletContext对象
ServletContext getServletContext();