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/line
System.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;
}
@Override
public 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的映射路径— 也是服务端地址
-
-