1 Request对象
1.1 Request概述
什么是Request
开发的软件都是B/S结构软件,从浏览器向服务器提交一些数据,将这些内容进行封装就封装成了一个请求对象(Request对象)。
Request对象获取客户端的请求数据, 最顶层的接口是ServletRequest,而我们用的是它的子接口HttpServletRequest继承ServletRequest.
HttpServletRequest接口的实现类是Tomcat引擎提供。
1.2 Request对象的API
获得客户端信息
方法 | 返回值 | 描述 |
---|---|---|
getMethod() | String | 获取请求的方法(Get / Set) |
getQueryString() | String | 获取请求路径后的提交参数的字符串 |
getRequestURI() | String | 获取请求路径的URI |
getRequestURL() | StringBuffer | 获取请求路径的URL |
getRemoteAddr() | String | 获取客户端的IP地址 |
getContextPath() | String | 获取WEB应用名称 |
演示代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>get请求方式</h1>
<form action="/day12_web/line2" method="get">
用户名:<input type="text" name="username" placeholder="请输入用户名"/><br />
密码:<input type="password" name="password" placeholder="请输入密码"/><br />
请选择您的爱好:
吃饭<input type="checkbox" name="check" value="eat" />
睡觉<input type="checkbox" name="check" value="sleep" />
打豆豆<input type="checkbox" name="check" value="hitbeanbean" /><br />
<input type="submit" value="提交"/>
</form>
<h1>post请求方式</h1>
<form action="/day12_web/line2" method="post">
用户名:<input type="text" name="username" placeholder="请输入用户名"/><br />
密码:<input type="password" name="password" placeholder="请输入密码"/><br />
请选择您的爱好:
吃饭<input type="checkbox" name="check" value="eat" />
睡觉<input type="checkbox" name="check" value="sleep" />
打豆豆<input type="checkbox" name="check" value="hitbeanbean" /><br />
<input type="submit" value="提交"/>
</form>
</body>
</html>
/**
* Request对象获得客户机信息
*/
@WebServlet(urlPatterns = "/line2")
public class RequestDemo1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获得请求方式:
System.out.println("请求方式:"+request.getMethod());
// 获得客户机的IP地址:
System.out.println("客户机IP地址:"+request.getRemoteAddr());
// 获得请求参数的字符串
System.out.println("请求参数的字符串:"+request.getQueryString());
// 获得请求路径的URL和URI
System.out.println("请求路径的URL:"+request.getRequestURL());
System.out.println("请求路径的URI:"+request.getRequestURI());
// 获取WEB应用名称(重点)
System.out.println("WEB名称为:"+request.getContextPath()); // "WEB名称为:/day12_web
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
利用获取WEB应用名称的方法,可以将重定向的地址写成不是固定的,方便之后调用。例如:
response.sendRedirect(request.getContextPath()+"/servlet2");
获得请求头的方法
方法 | 返回值 | 描述 |
---|---|---|
getHeader(String name) | String | 获得一个key对应一个value的请求头 |
getHeaders(String name) | Enumeration | 获得一个key对应多个value的请求头 |
代码演示:
/**
* Request对象获得请求头的方法
*/
@WebServlet(urlPatterns = "/line2")
public class RequestDemo1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获得请求头的信息
System.out.println("获得客户机浏览器类型:"+request.getHeader("User-Agent"));
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
请求头里面有个键——referer。其对应的值是:上一个页面的来源。利用这个可以做防盗链
String referer = request.getHeader("referer");
获得请求参数的方法(非常重要)
方法 | 返回值 | 描述 |
---|---|---|
getParameter(“表单中的name值”) | String | 获得提交的参数(一个name对应一个value) |
getParameterValues(“表单中的name值”) | String[] | 获得提交的参数(一个name对应多个value) 一键多值 |
getParameterMap() | Map | 获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中 |
代码演示
- 静态页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>request接收表单参数</h1>
<form action="/web01/RequestDemo2" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"><br/>
性别:<input type="radio" name="sex" value="man"/>男<input type="radio" name="sex" value="woman"/>女<br/>
籍贯:<select name="city">
<option value="beijing">北京市</option>
<option value="shanghai">上海市</option>
<option value="shenzhen">深圳市</option>
</select><br/>
爱好:<input type="checkbox" name="hobby" value="basketball"/>篮球
<input type="checkbox" name="hobby" value="football"/>足球
<input type="checkbox" name="hobby" value="volleyball"/>排球<br/>
自我介绍:<textarea name="info" rows="3" cols="8"></textarea><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
- servlet
/**
* Request接收表单参数
*/
@WebServlet(urlPatterns = "/RequestDemo2")
public class RequestDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 接收用户名和密码:
String username = request.getParameter("username");
String password = request.getParameter("password");
// 接收性别和籍贯:
String sex = request.getParameter("sex");
String city = request.getParameter("city");
// 接收爱好:
String[] hobby = request.getParameterValues("hobby");
// 接收自我介绍
String info = request.getParameter("info");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
System.out.println("性别:"+sex);
System.out.println("籍贯:"+city);
System.out.println("爱好:"+Arrays.toString(hobby));
System.out.println("自我介绍:"+info);
// 使用getParameterMap接收数据:
Map<String, String[]> map = request.getParameterMap();
for (String key:map.keySet()) {
String[] value = map.get(key);
System.out.println(key+" "+Arrays.toString(value));
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
1.3 Request对象接收表单请求参数的中文乱码处理
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>request接收中文数据</h1>
<h3>POST方式接收中文</h3>
<form action="/web01/RequestDemo3" method="post">
姓名:<input type="text" name="name"/><br/>
<input type="submit" value="提交">
</form>
<h3>GET方式接收中文</h3>
<form action="/web01/RequestDemo3" method="get">
姓名:<input type="text" name="name"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
POST方式接收中文
- 产生乱码的原因:
- post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区就有编码(默认ISO-8859-1:不支持中文).
- 解决方案:
- 将request的缓冲区的编码修改了即可。
/**
* 演示post方式处理中文乱码
*/
@WebServlet(urlPatterns = "/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置缓冲区的编码
request.setCharacterEncoding("UTF-8");
//接收数据
String name = request.getParameter("name");
System.out.println("姓名:"+name);
}
}
GET方式接收中文
- 产生乱码原因:
- get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了。
- 解决方案:
- 将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。
@WebServlet(urlPatterns = "/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
/**
* 演示get方式处理中文乱码
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 接收数据:
// request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
/*
String encode = URLEncoder.encode(name, "ISO-8859-1");
String decode = URLDecoder.decode(encode, "UTF-8");
System.out.println("姓名:"+decode);
*/
//在tomcat8之后,get方式的请求已经支持中文,所以不用再手动的这是编码.
String value = new String(name.getBytes("ISO-8859-1"),"UTF-8");
System.out.println("姓名:"+value);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
若要输出的数据有中文,那么在取出数据之前,一定要先设置中文的字符集。若取出来之后再设置,就还是用的默认的字符集。就会出现乱码的现象。
tomcat版本:8.5及以上版本
GET请求方式,request对象使用的字符集默认为utf-8
POST请求方式,request对象使用的字符集默认为ISO8859-1
解决:
设置request对象的字符集为utf-8
request.setCharacterEncoding("utf-8");
tomcat版本:8.5以下版本(了解)
没有设置request的字符集
GET:??????
POST:??????
request.setCharacterEncoding("utf-8"); 只针对post方式有效
GET:??????
POST:你好
解决:
request对象默认字符集ISO8859-1
1.String类中的方法:可以把获取到的ISO8859-1编码的字符串转换为字节数组
byte[] getBytes(Charset charset) 使用指定的字符集把字符串转换为字节数组
2.String类的构造方法:把字节输出以UTF-8的方式解码为字符串
String(byte[] bytes, String charsetName) 把字节数组,根据字符集转换字符串
2 Request域对象
作用域: Request域对象的作用域比较小,范围是一次请求有效
再一次请求无效
- 域对象存储数据: setArratibute(String key, Object value)
- 取出域对象数据: Object getAttribute(String key)
- 移除域对象数据: removeAttribute(String key)
@WebServlet(urlPatterns = "/servlet1")
public class Demo05Servlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//域对象存储数据: setArratibute(String key, Object value)
request.setAttribute("hello","java");
//取出域对象数据: Object getAttribute(String key)
Object value = request.getAttribute("hello");
System.out.println("servlet1:"+value);
}
}
@WebServlet(urlPatterns = "/servlet2")
public class Demo06Servlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//取出域对象数据: Object getAttribute(String key)
Object value = request.getAttribute("hello");
System.out.println("servlet2:"+value);
}
}
扩展:(下面是按作用域由大到小排名)
- ServletContext:作用域时整个web项目;即这个web项目里的所有Servlet都可以访问。
- Session:只要浏览器不关闭就有效。就算是访问不同的虚拟地址也可以。但只能保留30分钟。
- Request:只要是地址栏不变,不刷新,就有效,即只能请求一次。转发也有效。但是重定向就无效了。因为转发的地址栏不变,重定向的地址栏发生变化了。
- PageContext:只在jsp本页面有效。