Request
一、说明
前面说了我们将项目发布到Tomcat服务器中去之后,外部可以通过互联网来进行访问我们的部署到服务中的资源。
访问方式
http://ip地址:端口号/项目路径/资源路径
同时说了,还可以向服务器中传递用户传递的参数,然后服务器接收到了参数之后,servlet可以用来进行处理。
那么这章将详细描述如何接收参数?如何进行处理?下一节讲述如何去进行相应。
二、请求中的参数说明
当用户发送了请求之后,可以看到是通过HTTP的方式来进行请求访问的,那么通过抓包工具来获取对应的请求
// 请求行
// 请求方式 项目名称和请求路径 什么协议
POST /day16/req HTTP/1.1
// 请求头:通过key-value的形式
// 发送请求的主机IP地址
Host: localhost
// 连接方式是短连接还是长连接
Connection: keep-alive
// 请求的内容长度
Content-Length: 25
Cache-Control: max-age=0
// 请求是从哪里发送过来的
Origin: http://localhost
Upgrade-Insecure-Requests: 1
// 请求的内容类型
Content-Type: application/x-www-form-urlencoded
// 请求的浏览器类型,具体的版本和本机的系统类型
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
// 本机中的浏览器可以接受的响应的响应格式:xml、text、image等等
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://localhost/day16/index.jsp
// 可以接受的压缩格式
Accept-Encoding: gzip, deflate, br
// 浏览器可以接受的语言类型
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,cs;q=0.7
// 当前浏览器访问要请求的网址携带过去的cookie数据
Cookie: JSESSIONID=844ABB8A9F63FA147D8194E47C4BB1AF
// 请求体
// post方式的请求参数。get方式的请求参数是直接在请求行中
username=tom&password=tom
三、Request简介
request代表的是请求的对象,Tomcat服务器利用request来封装来自用户的请求数据,包括上面所有的数据。
request是HttpServletRequest的实例对象。
面试题:
当用户在浏览器端输入了对应的URL之后,接下来会发生什么?
http://localhost:8080/servletOne/index.html
第一步:
Tomcat服务器会将上面的内容进行解析:
项目名称:/servletOne
资源路径:index.html(静态资源)
第二步:
Tomcat去首先找到这个项目名称进行映射到对应的项目名称
第三步:
去资源路径下寻找有没有这个静态资源index.html文件,如果匹配了就可以利用response对象来进行展示了
注意:Tomcat服务器在针对于一次请求的时候,会直接创建request对象和response对象
request对象可能不止一个,但是response对象只有一个。因为前面提到了一次请求必定会存在着一次响应,多次请求必然也存在着多次响应。
哪怕响应的内容是错误的,但是也是响应。
3.1、利用request来获取请求行中的数据
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getMethod() | 获取请求方式 | String | |
getContextPath() | 获取项目路径 | String |
java代码如下
@WebServlet(name = "Servlet2",urlPatterns = "/two")
public class TwoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取得到请求方式
String method = request.getMethod();
System.out.println(method);
// 获取得到请求的项目路径
String contextPath = request.getContextPath();
System.out.println(contextPath);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
在浏览器端输入:
http://localhost:8080/servlet/two
查看控制台:
GET -----------请求方式是get
/servlet -----------项目名称
3.2、利用request来获取请求体中的参数
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getParameter(name) | 获取一个表单项的值 | name:表单项名称 | String |
getParameterValues(name) | 获取一个表单项的值 | String[] | |
getParameterMap() | 获取所有表单项的值 | Map<String,String[]> |
1、既然是请求体,那么需要来根据表单来进行提交;
2、根据返回值的类型可以看到获取单个参数、多个参数的值;
3、从浏览器中发送到Tomcat服务器中的数据首先都是经过二进制流的,所以在对二进制流解析的时候也是需要进行注意的。
国内的浏览器中是支持utf-8的,但是在进行解析二进制流之后,在服务器端进行解析的时候,服务器根据不同的请求方式(get/post)来进行解析。在Tomcat8之后,对get解析是utf-8,对于post请求方式采用的是iso8859-1方式解析。所以如果说我们利用post方式来进行请求的时候,我们需要在代码中指定对浏览器中发送过来的数据使用什么样的格式来解析二进制流。
index.html页面中的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单请求</title>
</head>
<body>
<form action="/servlet/three" method="post">
用户名:<input type="text" name="username"><br>
爱好:
<input type="checkbox" name="hobby" value="eat">吃
<input type="checkbox" name="hobby" value="drink">喝
<input type="checkbox" name="hobby" value="play">玩
<br>
<input type="submit" value="post提交">
</form>
</body>
</html>
对应的servlet代码如下:
@WebServlet(name = "Servlet3",urlPatterns = "/three")
public class ThreeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置针对于post方式的请求来说将二进制流解析成utf-8的方式
request.setCharacterEncoding("utf-8");
// 获取表单中的参数
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> parameterKeys = parameterMap.keySet();
for (String parameterKey : parameterKeys) {
String[] strings = parameterMap.get(parameterKey);
System.out.print(parameterKey+"对应的value有:");
for (String string : strings) {
System.out.print(string+" ");
}
System.out.println();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
在浏览器中访问:
http://localhost:8080/servlet/index.html
填写对应数据,去看下后端响应:
username对应的value有:李广
hobby对应的value有:eat drink play
可以看到可以使用getParameterMap来进行接收之前,指定对应的二进制流解析方式
3.3、request其它作用
-
域对象:由Servlet规范提供的,能临时存储数据的对象;在其作用范围里,数据可以共享。
-
所有域对象都可以存储数据:
- 存数据:
setAttribute(String name, Object value)
- 取数据:
getAttribute(String name)
- 删数据:
removeAttribute(String name)
- 存数据:
-
使用域对象进行数据共享的原则:在满足要求的情况下,使用小的域对象
-
不同域对象的区别是:作用范围不同
-
ServletContxt:
- 何时创建:服务器启动时
- 何时销毁:服务器关闭时
- 作用范围:整个web项目
但是这个是不常用的,因为在启动之后,就开启往里面存储数据,那么最终导入服务器内存消耗过大,影响效率。
-
request:
- 何时创建:一次请求开始
- 何时销毁:一次请求结束(开始响应时)
- 作用范围:一次请求中
-
四、请求转发和重定向区别
参照下面的API来进行操作:
//请求转发,是服务端跳转
request.getRequestDispatcher("/资源路径").forward(request, response);
//回顾:重定向,是浏览器跳转
response.sendRedirect("/项目路径/资源路径");
在静态页面中向servlet发送转发,需要带上项目路径;
servlet向servlet之间发送请求,不需要带上路径;
请求转发:
1、地址栏中不会发生变化;【最直观的区别】
2、请求转发是一次请求;
3、服务器间发生变化;
重定向:
1、地址栏中会发生变化;【最直观的区别】
2、重定向是两次请求;
3、浏览器间发生请求;
对于请求转发和重定向之间如何进行选择?
请求转发是一次请求中,在服务器之间转发,可能会携带数据;
重定向之间是浏览器请求服务器之后,然后服务器响应了浏览器之后,浏览器向其他服务器发送请求。此时携带的数据没有太大的意义;
例子如下:
------------------------------------------请求转发-----------------------------------------------------------
@WebServlet(name = "Servlet4",urlPatterns = "/four")
public class FourServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求转发
request.getRequestDispatcher("/five").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
@WebServlet(name = "Servlet5",urlPatterns = "/five")
public class FiveServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("hello,world");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
--------------------------------------------重定向-----------------------------------------------------------
@WebServlet(name = "Servlet6",urlPatterns = "/six")
public class SixServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置重定向
response.sendRedirect("http://www.baidu.com");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
输入以下路径:
http://localhost:8080/servlet/four
会发现浏览器端不会发生变化
输入以下路径:
http://localhost:8080/servlet/six
回车之后,会发现跳转到了
https://www.baidu.com/