什么时候会调用
在学 HTML 表单的时候学习过 form 标签有两个重要的属性,其中一个属性是 method 属性,它有两个值,一个值是 get,一个值是 post。
没错,我们的 doGet 方法和 doPost 方法就和两个参数有关系。当 form 的 method 属性值是 get 时,在提交表单的时候会调用 doGet 方法;当 form 的 method 属性值是 post 时,在提交表单的时候会调用 doPost 方法。
doGet 和 doPost 方法的使用
先看下 doGet 和 doPost 方法的声明
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
这两个方法的使用比较相似,都是和两个参数相关,doPost 方法默认是调用 doGet 方法。
下面主要以 doGet 方法作为演示,doPost 的使用和 doGet 没什么区别。
获取 Web 端数据
既然 doGet 和 doPost 方法和表单的提交相关,那么他们的使用自然就绕不开获取表单提交的数据了。
而获取网页端(表单标签)传递的数据需要用到 HttpServletRequest 类的对象(也就是 doGet 和 doPost 方法的第一个参数)。
1. getParameter(String name)
方法的参数 name 就是需要获取的名字,也就是我们在 HTML 表单标签中的 name 属性。
<form action="/JavaWeb1/TestServlet" method="get">
<input type="text" name="user" />|
<input type="password" name="password" />|
<input type="submit" value="提交" />|
</form>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("user");
String pass = request.getParameter("password");
System.out.println(name + " " + pass);
}
如果无法接收中文,需要使用request.setCharacterEncoding("UTF-8");
来将编码设置为 UTF-8。
2. getParameterValues(String name)
getParameter(String name)
只适用于传递的值只有一个的标签,例如输入框、单选框、默认的下拉框等,而对于复选框这种传递的值可能不止一个的标签时,需要使用getParameterValues(String name)
方法来获取。
<input type="checkbox" name="habbities" value="habbit1" />篮球
<input type="checkbox" name="habbities" value="habbit2" />足球
<input type="checkbox" name="habbities" value="habbit3" />游泳
String[] values = request.getParameterValues("habbities");
System.out.println(Arrays.toString(values));
3. getParameterMap()
getParameterMap()
获取的是表单传递的所有参数名和参数值,返回的是一个 Map 集合,其中 key 是获取值的标签的 name 属性,value 是对应的值,这个值可以是多个。
Map<String, String[]> paramMap = request.getParameterMap();
for (Entry<String,String[]> entry : paramMap.entrySet()) {
System.out.println(entry.getKey() + "\t" + Arrays.toString(entry.getValue()));
}
}
4. getParameterNames()
返回一个可遍历的枚举类型的字符串,它得到的是表单传递的所有参数的参数名。
Enumeration<String> names = request.getParameterNames();
while(names.hasMoreElements()) {
String paramName = names.nextElement();
System.out.println(paramName);
}
Java 端响应
request 参数主要完成从网页端获取数据,而 response 参数主要完成的是 Java 端对网页的响应。
1. 使用流的形式进行响应
这个方式了解一下就行,基本没有用这个的。
Eclipse 自动生成的 doGet 方法中,会自带下面的语句,这就是使用流的形式进行响应,页面会出现一段字符串。
response.getWriter().append("Served at: ").append(request.getContextPath());
除了显示字符串之外,还可以显示 HTML 文件
PrintWriter wr = response.getWriter();
wr.append("<html><head><meta charset=\"UTF-8\"></head><body>");
wr.write("<table><tr><th>1</th><th>2</th><th>3</th></tr></table>");
wr.write("</body></html>");
wr.flush();
wr.close();
wr=null;
响应访问的路径:

如果希望写入中文,需要加上response.setCharacterEncoding("UTF-8");
,如果写回的是 html 的话,还需要加上response.setContentType("text/html; charset=UTF-8");
2. 跳转
除了以上面流的方式访问 HTML 网页之外,还可以以跳转的方式访问。
2.1. 请求转发
例如,
String path = "/D20210221/index.html";
request.getRequestDispatcher(path).forward(request,response);
其中 path 是请求转发的路径,该路径是标准路径中工程名之后的路径。在我的示例中,访问 index.html 的标准路径是:http://127.0.0.1:8080/JavaWeb1/D20210221/index.html
,所以我的请求转发路径是:/D20210221/index.html
。
请求转发可以转发到网页,也可以转发到 Servlet。
请求转发访问的路径:

2.2. 请求重定向
例如,
String path = "/JavaWeb1/D20210221/index.html";
response.sendRedirect(path);
其中 path 是请求重定向的路径,该路径是标准路径中包括工程名在内的工程名之后的路径。在我的示例中,访问 index.html 的标准路径是:http://127.0.0.1:8080/JavaWeb1/D20210221/index.html
,所以我的请求重定向路径是:/JavaWeb1/D20210221/index.html
。
请求重定向可以转发到网页,也可以转发到 Servlet。
注意使用请求重定向的访问的路径和前两种方法访问的路径有所不同:

不论是流的方式响应,还是请求转发或者请求重定向,都是让 Servlet 结束,所以在其后不要在写代码了,不然的话运行时会出现一些莫名其妙的问题。
请求转发和请求重定向区别
请求转发 | 请求重定向 |
---|
在服务器端完成 | 在客户端完成 |
必须在同一台服务器下完成 | 可以在不同服务器下完成 |
相同的请求 | 两次不同的请求 |
速度快(不需要到客户端) | 速度慢 |
地址栏没有变化(Servlet地址) | 地址栏有变化(重定向的地址) |
注意,前后请求是否相同决定我们使用哪种方式来进行跳转,如果希望在跳转之后的页面中同样能从请求中获取数据,那么需要使用请求转发;如果跳转的页面中数据不需要从前一个页面中获取,那么使用请求重定向。