一、概念
- HttpServletRequest是一个接口,其父接口是ServletRequest
- HttpServletRequest是Tomcat将请求报文转换封装而来的对象,在Tomcat调用service方法时传入
- HttpServletRequest代表客户端发来的请求,所有请求中的信息都可以通过该对象获得
二、常见API
1)获取请求行信息相关(方式,请求的url,协议及版本)
API | 功能解释 |
---|---|
StringBuffer getRequestURL(); | 获取客户端请求的url |
String getRequestURI(); | 获取客户端请求项目中的具体资源 |
int getServerPort(); | 获取客户端发送请求时的端口 |
int getLocalPort(); | 获取本应用在所在容器的端口(有可能会有代理) |
int getRemotePort(); | 获取客户端程序的端口 |
String getScheme(); | 获取请求协议 |
String getProtocol(); | 获取请求协议及版本号 |
String getMethod(); | 获取请求方式 |
@WebServlet("/servlet04")
public class Servlet04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 行相关 GET/POST uri http/1.1
System.out.println(req.getMethod()); // 获取请求方式
System.out.println(req.getScheme()); // 获取请求协议
System.out.println(req.getProtocol()); // 获取请求协议及版本
System.out.println(req.getRequestURI()); // 获取请求的uri(统一资源标识符),项目内的资源路径
System.out.println(req.getRequestURL()); // 获取请求的url,项目内资源的完整的路径
}
}
URI 统一资源标识符 interface URI{} 资源定位的要求和规范 动物类
URL 统一资源定位符 class URL implements URI{} 一个具体的资源路径,可以理解为URI的实现 哺乳动物类
URI打印出来的是 /d02/servlet04
,而 URL 打印出来的是 http://localhost:8080/d03/servlet04
。细品,URL打印出来的是完整的URL,包含自己的IP和端口号,但如果将这个项目部署到一个测试环境中,或者其他的服务器上,那这个IP和端口号有可能是会发生变化的,但是后面的资源路径是不变的,否则前端请求的资源可能会出现问题。
2)获得请求头信息相关
API | 功能解释 |
---|---|
String getHeader(String headerName); | 根据头名称获取请求头 |
Enumeration<String> getHeaderNames(); | 获取所有的请求头名字 |
String getContentType(); | 获取content-type请求头 |
// 头相关 key:value key:value ....
// 根据名字单独获取某个请求头
String accept = req.getHeader("Accept");
System.out.println("Accept:" + accept);
// 获取本次请求中所有的请求头的名字
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String hname = headerNames.nextElement();
System.out.println(hname + ":" + req.getHeader(hname));
}
3)获得请求参数相关
PS:参数是严格区分大小写的,前端写的是什么参数名,后端就需要根据相同参数名进行获取
API | 功能解释 |
---|---|
String getParameter(String parameterName); | 根据请求参数名获取请求单个参数值 |
String[] getParameterValues(String parameterName); | 根据请求参数名获取请求多个参数值数组 |
Enumeration<String> getParameterNames(); | 获取所有请求参数名 |
Map<String, String[]> getParameterMap(); | 获取所有请求参数的键值对集合 |
BufferedReader getReader() throws IOException; | 获取读取请求体的字符输入流 |
ServletInputStream getInputStream() throws IOException; | 获取读取请求体的字节输入流 |
int getContentLength(); | 获得请求体长度的字节数 |
由于是获得请求参数,我们可以准备一个form表单,然后由form表单向servlet里面发请求。
web/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="get" action="servlet05">
<input type="text" name="username"><br>
<input type="password" name="userPwd"><br>
爱好:<br>
<input type="checkbox" name="hobby" value="1"> 篮球
<input type="checkbox" name="hobby" value="2"> 足球
<input type="checkbox" name="hobby" value="3"> 排球
<input type="checkbox" name="hobby" value="4"> 乒乓球<br>
<input type="submit">
</form>
</body>
</html>
Servlet
package com.atguigu.servlet;
public class Servlet05 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取键值对应的单个参数
String username = req.getParameter("username");
System.out.println(username);
String userPwd = req.getParameter("userPwd");
System.out.println(userPwd);
// 根据参数名字获取多个参数值【复选框】
// 如果hobby勾选了多个,传递的形式就是这样的:?hobby=篮球&hobby=足球
String[] hobbies = req.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbies));
// 获取所有的参数名
Enumeration<String> pnames = req.getParameterNames();
while (pnames.hasMoreElements()) {
String pname = pnames.nextElement();
// 由于我现在不确定pname获取到的参数值是单个值的还是多个值的,那么我们就把值当成多个参数值的来使用
String[] values = req.getParameterValues(pname);
if (values.length > 1) {
System.out.println(pname + "=" + Arrays.toString(values));
} else {
System.out.println(pname + "=" + values[0]);
}
}
// 返回所有参数的map集合 key = 参数名 value = 参数值
Map<String, String[]> parameterMap = req.getParameterMap();
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
for (Map.Entry<String, String[]> entry : entries) {
String pname = entry.getKey();
String[] value = entry.getValue();
if (value.length > 1) {
System.out.println(pname + "=" + Arrays.toString(value));
} else {
System.out.println(pname + "=" + value[0]);
}
}
/*
* 以上API专门用于获取key=value形式的参数,无论这些参数是在url后还是在请求体中
*
* form 表单标签提交GET请求时,参数以键值对形式放在url后,不放在请求体里,GET方式的请求也是可以有请求体
* 意思就是说GET方式也是可以有请求体的,只不过form表单的GET请求方式不往请求体中放而已。
* 因此上面我并没有说无论是GET请求方式还是POST请求方式,而说的是:无论这些参数是在url后还是在请求体中
* 请求方式只是代表一种方式而已,它并不是说这个方式就限定了我的请求体里面必须怎么样
*
*/
/**
* 获取请求体中的非键值对数据:例如JSON字符串、文件(说白了就是一串1010信息)
*/
// 获取一个从请求体中读取字符串的字符输入流
BufferedReader reader = req.getReader(); // JSON串
// 获取一个从请求中读取二进制数据字节的输入流
ServletInputStream inputStream = req.getInputStream(); // 读取文件
}
}
4)其他API
API | 功能解释 |
---|---|
String getServletPath(); | 获取请求的Servlet的映射路径 |
ServletContext getServletContext(); | 获取ServletContext对象 |
Cookie[] getCookies(); | 获取请求中的所有cookie |
HttpSession getSession(); | 获取Session对象 |
void setCharacterEncoding(String encoding); | 设置请求体字符集 |
System.out.println(req.getServletPath());