JavaWeb三大组件之Servlet技术(二)请求转发与重定向
1.HttpServletRequest类
1.1 HttpServletRequest类的作用
每次有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到sevice方法(doGet和doPost)给我们使用。可以通过HttpServletRequest对象,获取所有请求的信息。
1.2 HttpServletRequest类的常用方法
HttpServletRequest类的常用方法 |
---|
getRequestURI() :获取请求的资源路径 | getRequestURL() :获取请求的统一资源路径(绝对路径) | getRemoteHost() :获取客户端的ip地址 | getHeader() :获取请求头 | getParameter():获取请求的参数 | getParameterValues():获取请求的参数(多个值的时候使用) | getMethod() :获取请求的方式GET或POST | setAttribute(key,value); 设置域数据 | getAttribute(key); 获取域数据 | getRequestDispatcher(); 获取请求转发对象 |
使用HttpServletRequest类来获取请求的资源路径、绝对路径、客户端的ip地址、获取请求头:
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("URI==>"+req.getRequestURI());
System.out.println("URL==>"+req.getRequestURL());
System.out.println("客户端ip地址==>"+req.getRemoteHost());
System.out.println("请求头User-Agent ==>>"+req.getHeader("User-Agent"));
System.out.println("请求的方式==>"+req.getMethod());
}
}
运行后的结果为: 
使用HttpServletRequest类获取请求参数:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/05_ServletTest/parameterServlet">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
兴趣爱好:<input type="checkbox" name="hobby" value=cpp>C++
<input type="checkbox" name="hobby" value=java>Java
<input type="checkbox" name="hobby" value=js>JavaScript<br>
<input type="submit">
</form>
</body>
</html>
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
}
}
运行后的结果为: 
doGet 请求的中文乱码解决:
String username = req.getParameter("username");
username = new String(username.getBytes("iso-8859-1"), "UTF-8");
POST请求的中文乱码解决
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
req.setCharacterEncoding("UTF-8");
System.out.println("-------------doPost------------");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
System.out.println("兴趣爱好:" + Arrays.asList(hobby));
}
2.请求的转发
请求转发是指,服务器接收到请求后,从一个资源跳转到另外一个资源的操作叫请求转发。
请求转发可以用下图进行详细解释: 
Servlet1程序代码:
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料)"+username);
req.setAttribute("key1","柜台1的章");
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
requestDispatcher.forward(req,resp);
}
}
Servlet2程序代码:
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料):"+username);
Object key1 = req.getAttribute("key1");
System.out.println("柜台1是否有章:"+key1);
System.out.println("Servlet2处理自己的业务");
}
}
运行后的结果为: 

3.请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端需要去新的地址访问(因为之前的地址可能已经废弃了)。
请求重定向的过程可以用下图进行详细解释: 
ResponseServlet1代码:
public class ResponseServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Response1程序执行了");
req.setAttribute("key1","value1");
resp.sendRedirect("http://www.baidi.com");
}
}
ResponseServlet2代码:
public class ResponseServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(req.getAttribute("key1"));
System.out.println("Response2代码执行了");
}
}
运行后的结果为: 
4.base标签的作用
下面展示了常用到相对路径的网页跳转中存在的一定问题: 
使用base标签可以设置页面相对路径工作时的参照地址,这样可以有效防止各个地址不同,调转后的地址错误的问题。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--base 标签设置页面相对路径工作时参照的地址
href 属性就是参数的地址值
-->
<base href="http://localhost:8080/05_ServletTest/a/b/">
</head>
<body>
这是 a 下的 b 下的 c.html 页面<br/>
<a href="../../index.html">跳回首页</a><br/>
</body>
</html>
下面对Web中的相对路径和绝对路径进行详细阐述:
web中的相对路径 |
---|
. 表示当前目录 | … 表示上一级目录 | 资源名 表示当前目录/资源名 |
web中的绝对路径 |
---|
绝对路径:http://ip:port/工程路径/资源路径 |
在实际开发过程中,路径都是用绝对路径(1.绝对路径 2.base+相对路径),而不是简单的使用相对路径。
web中/斜杠的不同意义
web中/斜杠的不同意义 |
---|
在web中/斜杠是一种绝对路径。 | /斜杠 如果被浏览器解析,得到的地址是:http://ip:port | /斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径。 |
5. HttpServletResponse类
5.1 HttpServletResponse类的作用
上面我们刚刚学习了HttpServletRequest类,HttpServletResponse类和HttpServletRequest类一样。客户端每次向服务器发送请求时,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。
HttpServletRequest表示客户端向服务器发送请求过来的信息,HttpServletResponse表示服务器响应给浏览器的信息。
当我们需要设置服务器回传给客户端的信息时,可以使用HttpServletResponse对象来进行设置。
5.2 服务器给客户端回传数据
服务器给客户端就回传数据时,通常要使用字节流或者字符流进行操作。下面对回传数据时,两个常用的输出流进行详细介绍。
回传数据时,两个输出流的介绍 | |
---|
字节流:getOutputStream() | 常用于下载(常用于二进制数据) | 字符流:getWriter() | 常用于回传字符串(常用) |
注意:两个流同时只能使用一个流。
public class ResponseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("服务器给客户端回传数据");
}
}
运行后的结果为: 
|