HttpServletRequest(Servlet)
介绍
- HttpServletRequest 对象代表客户端的请求
- 当客户端/浏览器通过 HTTP 协议访问服务器时,HTTP 请求头中的所有信息都封装在这个对象中
- 通过这个对象的方法,可以获得客户端信息。
常用方法
1.getRequestURI() 获取请求的资源路径 http://localhost:8080/servlet/loginServlet
2.getRequestURL() 获取请求的统一资源定位符(绝对路径)http://localhost:8080/servlet/loginServlet
3.getRemoteHost() 获取客户端的 主机, getRemoteAddr()
4.getHeader() 获取请求头
5.getParameter() 获取请求的参数
6.getParameterValues() 获取请求的参数(多个值的时候使用) , 比如 checkbox, 返回的是数组
7.getMethod() 获取请求的方式 GET 或 POST
8.setAttribute(key, value); 设置域数据
9.getAttribute(key); 获取域数据
10.getRequestDispatcher() 获取请求转发对象, 请求转发的核心对象
应用实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<h1>注册用户</h1>
<form action="http://localhost:8080/servlet/requestMethods"
method="post">
u: <input type="text" name="username"/><br><br>
p: <input type="password" name="pwd"/><br><br>
选择你喜欢的老师:
<input type="checkbox" name="hobby" value="hsp">韩顺平
<input type="checkbox" name="hobby" value="lh">老韩
<input type="checkbox" name="hobby" value="spls">顺平老师<br/><br/>
<input type="submit" value="注册用户"/>
</form>
</body>
</html>
package com.lzw.servlet.request;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HttpServletRequestMethods extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用request对象,获取表单提交的各种数据
System.out.println("HttpServletRequestMethods doPost() 被调用");
/***********************************
* 获取和http请求头相关信息
***********************************/
System.out.println("请求的资源路径URI= " + request.getRequestURI());
//http://主机/uri
System.out.println("请求的统一资源定位符(绝对路径)URL= " + request.getRequestURL());
System.out.println("请求的客户端ip 地址= " + request.getRemoteAddr());//本地就是127.0.0.1
//思考题:如发现某个ip 在10s中,访问的次数超过 100次,就封ip
//实现思路: 1用一个集合concurrentHashmap[ip:访问次数] 2[线程/定时扫描] 3 做成处理
// 获取http请求头的信息,可以指定其他,比如 User-Agent , Host等待
System.out.println("http请求头HOST= " + request.getHeader("Host"));
// 说明,如果我们希望得到请求的头的相关信息,可以使用request.getHeader("请求头字段")
System.out.println("请求的发起地址是=" + request.getHeader("Referer"));
// 请获取访问网站的浏览器是什么?
String userAgent = request.getHeader("User-Agent");
System.out.println("User-Agent= " + userAgent);
// 取出 Chrome, 取出最后
String[] s = userAgent.split(" ");
System.out.println("浏览器 = " + s[s.length-1].split("\\/")[0]);
//获取Cookie
//JSESSIONID
String cookie = request.getHeader("Cookie");
String cs[] = cookie.split("=");
char[] chars = cs[1].toCharArray();
System.out.print("取出JSESSIONID: ");
int i = 0;
while (true){
if(chars[i] == (59)){
break;
}
System.out.print(chars[i]);
i++;
}
System.out.println();
// 主要是Get / Post
System.out.println("http请求方式~= " + request.getMethod());
/***********************************
* 获取和请求参数相关信息, 注意要求在返回数据前,获取参数
***********************************/
//解决接收参数的中文乱码问题, 老师提示,写在 getParameter前.
request.setCharacterEncoding("utf-8");
//1. 获取表单的数据[单个数据]
//username=tom&pwd=&hobby=hsp&hobby=spls
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
//2. 获取表单一组数据
String[] hobbies = request.getParameterValues("hobby");
System.out.println("username = " + username);
System.out.println("pwd = " + pwd);
for (String hobby : hobbies) {
System.out.println("hobby = " + hobby);
}
//返回接收到的信息,给浏览器回显
//本质就是在http响应头,加上 Content-Type: text/html;charset=utf-8
//说 text/html 表示返回的数据类型,浏览器会根据这个类型来解析数据
// text/plain 表示返回的数据,请浏览器使用文本方式解析
// application/x-tar 表示返回的是文件,浏览器就会以下载文件的方式处理
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("提交的用户名 = " + username);
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
注意事项和细节
1.获取 doPost 参数中文乱码解决方案 , 注意 setCharacterEncoding("utf-8") 要写在request.getParameter()前
2.注意:如果通过 PrintWriter writer, 有返回数据给浏览器,建议将获取参数代码写在writer.print() 之前,否则可能获取不到参数值(doPost)
3.处理 http 响应数据中文乱码问题
//本质就是在http响应头,加上 Content-Type: text/html;charset=utf-8
response.setContentType("text/html;charset=utf-8");
请求转发
为什么需要
实际开发中,往往业务比较复杂,需要在一次请求中,使用到多个 Servlet 完成一个任务(Servlet 链, 流水作业) 如图

说明
- 实现请求转发:请求转发指一个 web 资源收到客户端请求后,通知服务器去调用另外一个 web 资源进行处理
- HttpServletRequest 对象(也叫 Request 对象)提供了一个 getRequestDispatcher 方法,该方法返回一个 RequestDispatcher 对象,调用这个对象的 forward 方法可以实现请求转发
- request 对象同时也是一个域对象,开发人员通过 request 对象在实现转发时,把数据通过 request 对象带给其它 web 资源处理
实现请求转发

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="http://localhost:8080/servlet/checkServlet" method="post">
u: <input type="text" name="username"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
package com.lzw.servlet.request;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CheckServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CheckServlet 被调用");
//根据用户名来确定该用户是什么身份
String username = request.getParameter("username");
//注意如果是同一个request对象,那么可以在不同的servlet中,是 getParameter
if("tom".equals(username)){
//分配
request.setAttribute("role", "管理员");
}else{
request.setAttribute("role", "普通用户");
}
//获取分发器
// 1. /managerServlet 写的是要转发的servlet的url
// 2. / 会被解析成 /servlet
// 3. forward(request, response) 表示把当前servlet的request对象和response对象,传递给下一个servlet使用
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/managerServlet");
requestDispatcher.forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
package com.lzw.servlet.request;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ManagerServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ManagerServlet 被调用");
String username = request.getParameter("username");
String role = (String)request.getAttribute("role");
//输出信息
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("用户名:" + username + "<br/>");
writer.print("角色:" + role);
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
注意事项
浏览器地址不会变化(地址会保留在第 1 个 servlet 的 url)
在同一次 HTTP 请求中,进行多次转发,仍然是一次 HTTP 请求
在同一次 HTTP 请求中,进行多次转发,多个 Servlet 可以共享 request 域/对象的数据(因为始终是同一个 request 对象)
可以转发到 WEB-INF 目录下
不能访问当前 WEB 工程外的资源
因为浏览器地址栏会停止在第一个 servlet ,如果你刷新页面,会再次发出请求(并且会带数据), 所以在支付页面情况下,不要使用请求转发,否则会造成重复支付