Request对象概述
方向: 浏览器 -> 服务器
负责获取客户端的请求数据
request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后服务器通过request对象的相关方法来获取这些数据。
-
查看Servlet中的service方法得知, Servlet中使用的ServletRequest接口, 而我们使用的是ServletRequest的子接口HttpServletRequest, 它继承自ServletRequest, 是与HTTP协议相关的Request请求对象
-
我们使用的子接口HttpServletRequest, 此接口对象由Tomcat引擎提供
-
可以实现客户端向服务器发出请求, 请求内容包括: 请求行,请求头,请求体
http请求
Request对象获取请求行
- API
方法 | 返回值 | 描述 |
---|---|---|
getMethod() | String | 获取提交的方式 (GET,POST) |
getRequestURI() | String | 获取请求的参数,请求服务器路径 |
getRequestURL() | StringBuffer | 获取请求的参数,请求服务器路径 |
getQueryString() | String | 获取请求行 问号后面的参数 (GET) |
getContextPath() | String | 获取WEB应用名称 |
- 代码演示
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//request对象方法 getMethod()获取客户端的请求方式String method = request.getMethod();System.out.println(method);//方法 String getRequestURI() 获取请求服务器路径//方法 StringBuffer getRequestURL() 获取请求服务器路径String URI = request.getRequestURI();StringBuffer URL = request.getRequestURL();System.out.println("URI=="+URI);// /web04/lineSystem.out.println("URL=="+URL);// http://localhost:8080/web04/line//方法 String getQueryString()获取请求行,?后面的所有参数String query = request.getQueryString();System.out.println(query);//user=tom&pass=123&//获取WEB应用名称 String getContextPath()String path = request.getContextPath();System.out.println(path);// /web04//获取WEB应用名称, 结合重定向使用//response.sendRedirect(request.getContextPath()+"/ddd");
}
Request对象获取请求头
请求头数据格式键值对, k:v
指导性信息,指导服务器
方法 | 返回值 | 描述 |
---|---|---|
getHeader(String name) | String | 获得一个key对应一个value的请求头 |
getHeaderNames() | Enumeration | 获取所有的请求头的键 |
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/** Enumeration getHeaderNames() 获取所有的请求头的键* 返回值Enumeration接口 (向量枚举)* 集合:1.0-1.1 Enumeration 集合1.2 迭代器* Iterator迭代器接口: hasNext() next()* Enumeration接口: hasMoreElement() nextElement()*/Enumeration<String> enums = request.getHeaderNames();while (enums.hasMoreElements()){key = enums.nextElement();String value = request.getHeader(key);System.out.println(key+"=="+value);}
}
Request获取请求参数
方法 | 返回值 | 描述 |
---|---|---|
getParameter(表单中的name值) | String | 获得提交的参数(一个name对应一个value) |
getParameterValues(表单中的name值) | String[] | 获得提交的参数(一个name对应多个value) |
getParameterMap() | Map<String,String[]> | 获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中 |
<body><form action="/web02/param" method="post">用户名:<input type="text" name="username"><br/>密 码:<input type="password" name="password"><br/>爱 好:<input type="checkbox" name="hobby" value="Basketball">篮球<input type="checkbox" name="hobby" value="football">足球<input type="checkbox" name="hobby" value="pingpang">乒乒球 <br/><input type="submit"></form>
</body>
@WebServlet(urlPatterns = "/param")
public class ParamServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获得提交的参数(一个name对应一个value)String username = request.getParameter("username");String password = request.getParameter("password");System.out.println(username +" == " +password);//获得提交的参数(一个name对应多个value)String[] hobbies = request.getParameterValues("hobby");System.out.println("hobbies = " + Arrays.toString(hobbies));//获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中Map<String, String[]> map = request.getParameterMap();for(String key : map.keySet()){String[] values = map.get(key);System.out.println(key + " == " + Arrays.toString(values));}}
Request对象接收表单请求参数的中文乱码处理
POST方式接收中文
- 产生乱码的原因:
- post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区就有编码(默认ISO-8859-1:不支持中文).
- 解决方案:
- 将request的缓冲区的编码修改了即可。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//将request的缓冲区的编码修改request.setCharacterEncoding("utf-8");//获取请求参数String user = request.getParameter("user");System.out.println("user = " + user);
}
GET方式接收中文
Tomcat8.5版本之后, Tomcat自动处理了get请求的中文乱码问题
但在Tomcat8.5之前的版本中, get请求的中文乱码需要自行处理
- 产生乱码原因:
- get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了。
- 解决方案:
- 将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/*get方式提交的数据在 请求行中Tomcat8.5之后, Tomcat自动处理了get请求的中文乱码问题, 但在之前的Tomcat版本中,get请求的中文乱码需要自行处理老版本Tomcat中文乱码的解决:将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。*/String user = request.getParameter("username"); ////将存入到request缓冲区中的值以ISO-8859-1的方式获取到byte[] bytes = user.getBytes("iso-8859-1");//以UTF-8的方式进行解码String value = new String(bytes, "utf-8");System.out.println("user = " + user);
}
BeanUtils 将 map中的数据封装到 pojo类中
导包
pojo类
package cn.itcast.pojo;import java.util.Arrays;public class User {private String username;private String password;private String[] hobby;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String[] getHobby() {return hobby;}public void setHobby(String[] hobby) {this.hobby = hobby;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +", hobby=" + Arrays.toString(hobby) +'}';}
}
页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="/web0202/demo15" method="post">用户名:<input type="text" name="username"><br/>密 码:<input type="password" name="password"><br/>爱 好:<input type="checkbox" name="hobby" value="Basketball">篮球<input type="checkbox" name="hobby" value="football">足球<input type="checkbox" name="hobby" value="pingpang">乒乒球 <br/><input type="submit">
</form>
</body>
</html>
servlet
package cn.itcast.web;import cn.itcast.pojo.User;
import org.apache.commons.beanutils.BeanUtils;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.lang.reflect.InvocationTargetException;
import java.util.Map;@WebServlet("/demo15")
public class ServletDemo15 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 解决服务器给浏览器的数据中文乱码问题response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");Map<String, String[]> parameterMap = request.getParameterMap();User user = new User();try {BeanUtils.populate(user, parameterMap);} catch (Exception e) {e.printStackTrace();}System.out.println(user);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
原理
通过map的key值得到set方法的名字,利用反射技术调用set方法,将value值传入
Request域对象
Request作为域对象的API
Request作为域对象作用范围
Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。
一次请求范围:从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。
如果是两次请求,那么两个request对象是不一样的,所以一个里面存储的内容另外一个是获取不到的
但是如果是一次请求,而这个请求,服务器进行转发的之后,依然是一个request对象,那么他们中存储的对象则是可以被获取到的
每次请求都会创建新的request对象, 当响应结束后立刻销毁request对象.
- API
方法 | 返回值 | 描述 |
---|---|---|
setAttribute(String name, Object obj) | void | 向Request域中保存数据 |
getAttribute(String name) | Object | 从Request域中获取数据 |
removeAttribute(String name) | void | 从Request域中移除数据 |
- 代码演示
servlet1
@WebServlet(urlPatterns = "/my1")
public class MyServlet1 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//向request域对象中 存值request.setAttribute("language","java");//从request域对象中 取值Object value = request.getAttribute("language");System.out.println("MyServlet1 value = " + value);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
servlet2
@WebServlet(urlPatterns = "/my2")
public class MyServlet2 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//从request域对象中 取值Object value = request.getAttribute("language");System.out.println("MyServlet2 value = " + value);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
请求转发
请求转发的写法
通过ServletRequest对象获得RequestDispatcher对象
方法 | 返回值 | 描述 |
---|---|---|
getRequestDispatcher(String path) | RequestDispatcher | 获得RequestDispatcher对象 |
再根据RequestDispatcher中的方法进行请求转发
方法 | 返回值 | 描述 |
---|---|---|
forward(ServletRequest request, ServletResponse response) | void | 进行请求转发 |
转发的实现步骤
- request对象方法获取转发器 RequestDispatcher getRequestDispatcher(“转发地址”)返回值就是转发器
- 使用转发器对象的方法 forward
代码实现
servlet1
@WebServlet(urlPatterns = "/my1")
public class MyServlet1 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//向request域对象中 存值request.setAttribute("language","java");//从request域对象中 取值Object value = request.getAttribute("language");System.out.println("MyServlet1 value = " + value);//进行请求转发request.getRequestDispatcher("/my2").forward(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
servlet2
@WebServlet(urlPatterns = "/my2")
public class MyServlet2 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//从request域对象中 取值Object value = request.getAttribute("language");System.out.println("MyServlet2 value = " + value);//响应回浏览器response.setContentType("text/html;charset=utf-8");response.getWriter().print("我是MyServlet2 页面数据");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
9 请求转发和重定向区别
- 请求转发是一次请求一次响应,而重定向是两次请求两次响应。
- 请求转发地址栏不会变化的,重定向地址栏发生变化。
- 请求转发路径不带工程名,重定向需要带工程名路径。
- 请求转发只能在本网站内部,重定向可以定向到任何网站。
9.2 代码演示
MyServlet1
@WebServlet(urlPatterns = "/my1")
public class MyServlet1 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//向request域对象中 存值request.setAttribute("language","java");//从request域对象中 取值Object value = request.getAttribute("language");System.out.println("MyServlet1 value = " + value);//进行请求转发//request.getRequestDispatcher("/my2").forward(request, response);//进行重定向response.sendRedirect("/web02/my2");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
MyServlet2
@WebServlet(urlPatterns = "/my2")
public class MyServlet2 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//从request域对象中 取值Object value = request.getAttribute("language");System.out.println("MyServlet2 value = " + value);//响应回浏览器response.setContentType("text/html;charset=utf-8");response.getWriter().print("我是MyServlet2 页面数据");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
- 注意:
- 如果需要使用request进行值传递,需要通过请求转发完成。
- 如果页面需要跳转到其他网站上必须使用重定向, 不能使用request进行值传递。
客户端与服务器端地址的写法
-
什么是客户端地址:客户端直接访问服务器的地址是客户端地址
- 通过客户端访问web应用 地址必须加上web应用的名称
-
什么是服务器端地址:web应用内部访问的地址是服务器端地址
- 特点,访问时,不用写web应用名称
-
写地址时, 怎么区分是否加上web应用的名称
- 看在web应用内, 还是外
- 客户端地址
- 直接在地址栏中写url地址 — 客户端地址
- 标签的href — 客户端地址
- form表单的action-----客户端地址
- location.href ---- 客户端地址
- response响应对象的重定向 sendRedirect( 地址) -----客户端地址
- 目前记住一个服务器端地址:
- Request请求对象的请求转发getRequestDispatcher(转发地址) — 服务器端地址
- servlet的映射路径— 也是服务端地址
- 客户端地址
- 看在web应用内, 还是外