目录
示例代码
这两个类生成的对象,我们称为request和response对象。全文均以此为准。
@WebServlet("/test")
public class TestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
System.out.println(servletContext);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
一、HttpServletRequest、HttpServletResponse概述
概述:request和response对象:这两个对象是由服务器创建的,request对象用于获取请求消息,response对象用于设置响应消息。
request和response对象的创建过程:
以tomcat创建request和response为例:
- tomcat服务器,根据请求url中的资源路径,创建对应的DemoServlet(继承HttpServlet接口)的对象;
- tomcat服务器,会创建request和response对象。request对象封装请求消息数据;
- tomcat服务器,将request和response两个对象传递给service方法,并且调用service方法;
- 开发者,通过request对象获取请求消息数据,通过response对象设置响应消息数据;
- tomca服务器,在给浏览器做出响应之前,会从response对象中获取开发者设置的响应消息数据;
二、HttpServletRequest 功能
2.1 获取请求消息
1. 获取请求行数据请求行示例:GET /03/demo1?username=master HTTP/1.1
String getMethod(); 获取请求方式:GET
String getContextPath(); 获取虚拟目录:/03 【掌握】
String getServletPath(); 获取Servlet路径:/demo1
String getQueryString(); 获取get方式的请求参数:username=master
String getRequestURI(); 获取请求的URI:/03/demo1 【掌握】
StringBuffer getRequestURL(); 获取请求的URL:http://localhost/03/demo1 【掌握】
String getProtocol(); 获取协议和版本号:HTTP/1.1
String getRemoteAddr(); 获取客户机的IP地址
示例代码:
// 1. 获取请求方式:GET
String method = request.getMethod();
System.out.println("获取请求方式 = " + method);
// 2. 获取虚拟目录:/03 【掌握】
String contextPath = request.getContextPath();
System.out.println("获取虚拟目录 = " + contextPath);
// 3. 获取Servlet路径:/requestdemo1
String servletPath = request.getServletPath();
System.out.println("获取Servlet路径 = " + servletPath);
// 4. 获取get方式的请求参数:username=master
String queryString = request.getQueryString();
System.out.println("获取get方式的请求参数 = " + queryString);
// 5. 获取请求的URI:/03/requestdemo1 【掌握】
String requestURI = request.getRequestURI();
System.out.println("获取请求的URI = " + requestURI);
// 6. 获取请求的URL:http://localhost:8080/03/requestdemo1 【掌握】
StringBuffer requestURL = request.getRequestURL();
System.out.println("获取请求的URL = " + requestURL);
// 7. 获取协议和版本号:HTTP/1.1
String protocol = request.getProtocol();
System.out.println("获取协议和版本号 = " + protocol);
// 8. 获取客户机的IP地址:0:0:0:0:0:0:0:1
String remoteAddr = request.getRemoteAddr();
System.out.println("获取客户机的IP地址 = " + remoteAddr);
输出结果:
获取请求方式 = GET
获取虚拟目录 = /03
获取Servlet路径 = /requestdemo1
获取get方式的请求参数 = null
获取请求的URI = /03/requestdemo1
获取请求的URL = http://localhost:8080/03/requestdemo1
获取协议和版本号 = HTTP/1.1
获取客户机的IP地址 = 0:0:0:0:0:0:0:1
user-agent 的应用:
// 获取 user-agent
String agent = request.getHeader("user-agent");
// 判断user-agent的浏览器版本
if (agent.contains("Chrome")) {
System.out.println("谷歌");
} else if (agent.contains("FireFox")) {
System.out.println("火狐");
} else {
System.out.println("其他");
}
System.out.println("user-agent : " + agent);
referer的应用:
// 防盗链功能
if (referer != null) {
if (referer.contains("/03")) {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("正常访问...");
System.out.println("正常访问");
} else {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("盗链...");
System.out.println("盗链,可以做一些引导页面");
}
}
- 获取请求头数据
Enumeration<String> getHeaderNames(); 获取所有的请求头名称
String getHeader(String var1); 通过请求头的名称(该方法var1不区分大小写)获取请求头的值 【掌握】
示例代码:
// 1. 获取所有的请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headName = headerNames.nextElement();
// 2. 通过请求头的名称获取请求头的值
String header = request.getHeader(headName);
System.out.println(headName + " : " + header);
}
- 获取请求体数据
只有POST请求方式,才有请求体。在请求体中封装了POST请求的请求参数。
步骤:
1. 获取流对象
1. BufferedReader getReader(); 获取字符输入流,只能操作字符数据
2. ServletInputStream getInputStream();获取字节输入流,可以操作所有字符数据
2. 然后把流对象转换成数据。
示例代码:
// 获取请求体数据
// 1. 获取字符流
BufferedReader br = request.getReader();
// 2. 读取数据
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
2.2 获取请求参数
获取请求参数的通用方式(GET/POST均可以使用)。
(常用)String getParameter(String var1); 根据参数名称获取参数值。注意:如果要获取复选框的值,需要使用方法 getParameterValues(常用)
例如:String username = request.getParameter("username"); // username=xxxx,获取username对应的value
String[] getParameterValues(String var1); 根据参数名称获取参数值的数组。多用于复选框
例如:hobby=xx&hobby=xxx&hobby=x
Enumeration<String> getParameterNames(); 获取所有请求的参数名
(常用)Map<String, String[]> getParameterMap(); 获取所有参数的map集合(也可以获取复选框的所有参数)(常用)
中文参数乱码问题
- get方式:tomcat8及以上版本已解决乱码问题。
- post方式:会乱码。
- 解决:在获取参数前,设置request的编码:request.setCharacterEncoding(“utf-8”);
示例代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求参数
System.out.println("-----获取请求参数-----");
String username = request.getParameter("username");
System.out.println("post username=" + username);
// 根据参数名称获取参数值的数组
System.out.println("-----根据参数名称获取参数值的数组,多用于复选框-----");
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("-----获取所有请求的参数名-----");
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = request.getParameter(name);
System.out.println(name + " : " + value);
}
System.out.println("-----获取所有参数的map集合-----");
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for (String key : keySet) {
// 根据key获取值
String[] strings = parameterMap.get(key);
for (String value : strings) {
System.out.println(key + " : " + value);
}
System.out.println("------------");
}
}
浏览器抓取接口,查看参数:
查看代码输入结果:
-----获取请求参数-----
post username=master
-----根据参数名称获取参数值的数组,多用于复选框-----
game
pragrammer
study
-----获取所有请求的参数名-----
username : master
password : 123
hobby : game
-----获取所有参数的map集合-----
username : master
------------
password : 123
------------
hobby : game
hobby : pragrammer
hobby : study
------------
测试可以得到:方法Map<String, String[]> getParameterMap();
可以有效的获取所有参数(包括复选框)
2.3 请求转发
一种在服务器内部的资源跳转方式。如图:
请求转发的特点:
1. 浏览器访问的地址不会发生变化;
2. 只能转发到当前服务器内部资源中;
3. 转发是一次请求
实现:
1. 通过request对象,获取请求转发器对象:RequestDispatcher getRequestDispatcher(String var1); 参数var1是转发资源路径。
2. 使用RequestDispatcher对象进行转发:void forward(ServletRequest request, ServletResponse response);
示例代码:
创建RequestDemo5,RequestDemo6两个对象。
实现需求:从RequestDemo5请求转发到RequestDemo6。
@WebServlet("/requestdemo5")
public class RequestDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("RequestDemo5 被访问了");
// 存储数据到request域中
request.setAttribute("key_msg", "obj_value");
// 请求转发
request.getRequestDispatcher("/requestdemo6").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
@WebServlet("/requestdemo6")
public class RequestDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取转发的数据
Object value = request.getAttribute("key_msg");
System.out.println("value=" + value);
System.out.println("RequestDemo6 被访问了");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
输出结果:
RequestDemo5 被访问了
value=obj_value
RequestDemo6 被访问了
上图:我们在RequestDemo5 中做了请求转发到 RequestDemo6 ,但是只有一个请求。证明了:转发是一次请求!!!
2.4 共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据。
request域:代表一次请求的范围。一般用于请求转发的多个资源中共享数据。
void setAttribute(String var1, Object var2); var1是key,var2是value。存储数据
Object getAttribute(String var1); var1是key。通过键获取值
void removeAttribute(String var1); var1是key。通过键移除键值对
示例代码和原理图:见 3. 请求转发示例代码。
2.5 ServletContext
ServletContext getServletContext();
详情,请见另一篇博客:传送门