HttpServletRequest请求对象接口
HttpServletRequest接口是Tomcat服务器提供的org.apache.catalina.connector.RequestFacade给实现的,它的父接口是 ServletRequest
public interface HttpServletRequest extends ServletRequest {}
public class RequestFacade implements HttpServletRequest {}
jakarta.servlet.http包下的类和接口
HttpServletRequest接口是用来封装“请求协议”中的数据的对象(请求域)是Servlet规范中的一员,全类名是jakarta.servlet.http.HttpServletRequest
HttpServletRequest对象创建和销毁的时机
获取查询字符串的方法
HttpServletRequest采用Map
#前端提交的数据格式:username=abc&userpwd=111&aihao=s&aihao=d&aihao=tt
#Map结构中key重复的时候value会覆盖
key value
---------------------
username abc
userpwd 111
aihao s
aihao d
aihao tt
#Map,采用String[]可以避免Map集合key重复的时候value覆盖问题
key value
-------------------------------
username {"abc"}
userpwd {"111"}
aihao {"s","d","tt"}
HttpServletRequest父接口是ServletRequest , ServletRequest接口的方法的子类可以直接继承
方法名 | 功能 |
---|---|
Map |
获取请求参数参数的Map集合形式 |
Enumeration< String > getParameterNames() | 获取Map集合中所有的key |
String[] getParameterValues(String name) | 根据Map集合的key获取Map集合的value |
String getParameter(String name) | 根据Map集合的key获取value这个一维数组当中的第一个元素(最常用),大部分一维数组中只有一个元素 |
获取请求参数的方式
#前端提交的数据username=zhangsan&userpwd=123&interest=s&interest=d会被服务器采用Map结构封装到request对象中
key value
---------------------------
"username" {"zhangsan"}
"userpwd" {"123"}
"interest" {"s", "d"}
#一维数组的toString()方法的输出形式
String[] values = {"abc", "def", "xyz"};
//[Ljava.lang.String;@2f92e0f4
System.out.println(values);
public class RequestTestServlet extends HttpServlet{
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException,ServletException{
// 获取包含请求参数Map集合
Map<String,String[]> parameterMap = request.getParameterMap();
// 通过Map集合的keySet方法获取Map集合中一个含有所有key的Set集合
Set<String> keys = parameterMap.keySet();
// 遍历集合中的key,获取其对应的一维数组value,如username=[Ljava.lang.String;@7cce40b4
Iterator<String> it = keys.iterator();
while(it.hasNext()){
String key = it.next();
String[] values = parameterMap.get(key);
System.out.println(key + "=" + values);
// 遍历获取到的一维数组的元素
System.out.print(key + "=");
for(String value : values){
System.out.print(value + ",");
}
// 换行
System.out.println();
}
// 通过request的getParameterNames方法获取这个Map集合的所有key
Enumeration<String> names = request.getParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
System.out.println(name);
String[] values = request.getParameterValues(name);
// 遍历获取到的一维数组的元素
for(String value : values){
System.out.print(value + ",");
}
System.out.println();
}
// 直接通过name获取value这个一维数组
String[] usernames = request.getParameterValues("username");
String[] userpwds = request.getParameterValues("userpwd");
String[] interests = request.getParameterValues("interest");
// 遍历一维数组的元素
for(String username : usernames){
System.out.println(username);
}
for(String userpwd : userpwds){
System.out.println(userpwd);
}
for(String interest : interests){
System.out.println(interest);
}
// 通过name获取value这个一维数组的第一个元素,因为这个一维数组中一般只有一个元素
String username = request.getParameter("username");
String userpwd = request.getParameter("userpwd");
// 获取的都是一维数组当中的第一个元素
System.out.println(username);
System.out.println(userpwd);
// 表单interest是个复选框有多个元素,需要获取整个数组
String[] interests = request.getParameterValues("interest");
// 遍历interests数组
for(String interest : interests2){
System.out.println(interest);
}
}
}
存储数据和转发的方法
request对象也叫“请求域”对象 , “请求域”对象要比“应用域”对象范围小很多
方法名 | 功能 |
---|---|
void setAttribute(String name, Object obj) | 向请求域当中绑定数据 |
Object getAttribute(String name) | 根据name从请求域当中获取数据 |
void removeAttribute(String name) | 将请求域当中绑定的数据移除 |
在BSevlet中拿不到AServelt中向请求域中存储的数据 ,因为这两个Servlet对应不同的请求即不同的请求域
// AServelt中向请求域中存储数据
public class AServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException{
// 获取系统当前时间
Date nowTime = new Date();
// 向request请求域当中绑定数据
request.setAttribute("sysTime", nowTime);
// 在AServlet当中new一个BServlet对象,然后调用BServlet对象的doGet方法并把request对象传过去也可以实现功能但不符合规范
// 每一个Servlet对象的创建不能自己由程序员来决定, 因为自己new的Servlet对象生命周期不受Tomcat服务器的管理
-
}
}
// BSevlet中取出AServelt中向请求域中绑定的数据
public class BServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException{
// 无法从request域当中取出绑定的数据
Object obj = request.getAttribute("sysTime");
// 输出到浏览器
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("request域当中获取的系统当前时间 = " + obj);
}
}
跳转方法(Servlet共享数据)
两个或者多个Servlet共享同一份数据的方式
请求转发的时候路径要以“/”开始且不加项目名, 转发的对象可以是静态的html或动态的Servlet,只要是Tomcat服务器当中的合法资源都可以转发
方法名 | 功能 |
---|---|
RequestDispatcher getRequestDispatcher(String path) | 获取请求转发器对象 |
把AServlet和BServlet放到一次请求当中, 即执行了AServlet之后立马跳转到BServlet保证两个Servlet在同一次请求当中
// AServelt向请求域中存储数据并转发到BSevlet
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取系统当前时间
Date nowTime = new Date();
// 将系统当前时间绑定到请求域当中
request.setAttribute("sysTime", nowTime);
// 第一步:先获取请求转发器对象,把"/b"这个路径包装到请求转发器当中,实际上是把下一个跳转的资源的路径告知给Tomcat服务器
//RequestDispatcher dispatcher = request.getRequestDispatcher("/b");
// 第二步:调用请求转发器RequestDispatcher的forward方法进行转发,转发的时候request和response都是要传递给下一个资源的
//dispatcher.forward(request, response);
// 转发到一个Servlet
request.getRequestDispatcher("/b").forward(request, response);
// 转发到一个HTML
// request.getRequestDispatcher("/test.html").forward(request, response);
}
}
// BSevlet中取出AServelt中向请求域中绑定的数据
public class BServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException{
// 可以从request域当中取出绑定的数据
Object obj = request.getAttribute("sysTime");
// 输出到浏览器
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("request域当中获取的系统当前时间 = " + obj);
}
}
获取请求参数和处理乱码方法
解决请求体(POST请求才有)含有中文时后端服务器接收数据时乱码问题: 通过request对象设置请求体的字符集request.setCharacterEncoding(“UTF-8”)
解决响应体含有中文时浏览器接收数据时乱码问题: 通过response对象设置响应体的字符集response.setContentType(“text/html;charset=UTF-8”)
对于Tomcat9及其之前版本,当浏览器发起POST请求和GET请求时服务器响应的数据含有中文时都会出现乱码问题
对于Tomcat10及其之后版本, 当浏览器发起POST请求和GET请求时服务器响应的数据含有中文时都不会出现乱码问题
方法名 | 功能 |
---|---|
String getRemoteAddr(); | 获取客户端的IP地址 |
void setCharacterEncoding(String) | 设置请求体的字符集 , 处理POST请求的乱码问题 |
String getContextPath() | 获取应用的根路径(底层还是调用ServletContext对象的方法) |
String getMethod() | 获取请求方式 |
String getRequestURI() | 获取请求的URI (带项目名) |
String getServletPath() | 获取Servlet 的路径 (项目名后面的路径) |
public class TestServlet extends HttpServlet{
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException{
// 获取客户端的IP地址
String remoteAddr = request.getRemoteAddr();
// 处理POST请求的乱码问题: 设置请求体的字符集
request.setCharacterEncoding("UTF-8");
// 解决Tomcat9及其之前版本响应乱码问题
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("你好Servlet");
// 获取应用的根路径
String contextPath = request.getContextPath();
// 获取请求方式
String method = request.getMethod();
// 获取请求的URI,/aaa/testRequest(aaa是项目名)
String uri = request.getRequestURI();
// 获取Servlet路径,/testRequest(不带项目名)
String servletPath = request.getServletPath();
}
}