servlet中的请求转发和重定向
请求转发
请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。
AServlet01.java文件
/**
* 请求转发
* 服务器的行为
* 地址栏不会发生改变
* 只有一个请求
*/
public class AServlet01 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("张家辉被请求去买水");
String money = request.getParameter("money");
System.out.println("张家辉请求转发给了万鲲");
// 请求转发
request.getRequestDispatcher("bs").forward(request, response);
}
}
BServlet02.java文件
public class BServlet02 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
System.out.println("万鲲被请求买水");
String money = request.getParameter("money");
if(money == null || "".equals(money)){
response.getWriter().write("不给钱,滚蛋");
return;
}
System.out.println("拿到" + money + "毛去买水");
PrintWriter out = response.getWriter();
out.write("这是一瓶超级好喝的自来水!");
out.close();
}
}
- 服务器请求AServlet01.java文件,AServlet01将请求转发给BServlet02.java文件,BServlet02进行对服务器的响应。
- AServlet01获取到的request对象的数据可以在请求转发后在BServlet02中获取。
- 请求转发浏览器地址栏路径不会发生改变,所以请求转发不能跨域,即不能转发到服务器以外的地址。
request作为域对象
通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。
request.setAttribute(String name, Object o); // 设置域对象内容
request.getAttribute(String name); // 获取域对象内容
request.removeAttribute(String name); //删除域对象内容
request 域对象中的数据在一次请求中有效,经过请求转发,request 域中的数据依然存在,则在请求转发的过程中可以通过 request 来传输/共享数据。
重定向
重定向是一种服务器指导客户端的行为。客户端发出第一个请求,被服务器接收,经过处理服务器进行响应,与此同时,服务器给客户端一个地址(下次请求的地resp.sendRedirect(“url”);),当客户端接收到响应后,立刻、马上、自动根据服务器给的地址进行第二个请求的发送,服务器接收请求并作出响应,重定向完成。从描述中可以看出重定向当中有两个请求存在,并且属于客户端行为。
AServlet01.java文件
public class AServlet01 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("张家辉被请求去买水");
String money = request.getParameter("money");
// 往request域对象存数据(格式 key:value)
request.setAttribute("小费", "0.1");
System.out.println("张家辉重定向给了万鲲");
// 重定向
response.sendRedirect("bs");
}
}
BServlet02.java文件
public class BServlet02 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
System.out.println("万鲲被请求买水");
// 从request作用域中获取数据
String smallmoney = (String)request.getAttribute("小费");
System.out.println("得到小费" + smallmoney);
String money = request.getParameter("money");
if(money == null || "".equals(money)){
response.getWriter().write("不给钱,滚蛋");
return;
}
System.out.println("拿到" + money + "毛去买水");
PrintWriter out = response.getWriter();
out.write("这是一瓶超级好喝的自来水!");
out.close();
}
}
- 重定向服务器会发送两次请求,所以不能将第一次请求的数据在第二次请求时传输,即重定向不能共享request对象中的数据。
- 由于第二次请求时浏览器发出的,所以浏览器地址栏会发生改变,可以实现跨域访问,即可以访问服务器以外的地址。
- 第一次请求获得的响应码为 302,并且含有一个 location 头信息。
请求转发和重定向的区别
请求转发(req.getRequestDispatcher().forward()) | 重定向(resp.sendRedirect()) |
---|---|
一次请求,数据在 request 域中共享 | 两次请求,request 域中数据不共享 |
服务器端行为 | 客户端行为 |
地址栏不发生变化 | 地址栏发生变化 |
绝对地址定位到站点后 | 绝对地址可写到 http:// |
请求时的路径问题
在请求资源时,必须给出正确的路径,否则是找不到资源的。路径分为相对路径和绝对路径,绝对路径可简单理解为完整路径,在 web 项目中绝对路径分两种,一种是以 http:// 开头的,该种绝对路径已经跨域,即任何地方的资源都能访问,另一种则是从当前域名|IP|主机后的端口号开始的,不能跨域,也属于一种绝对路径。相对路径则就是相对当前资源所在路径。
我们学的所有的请求可以分为客户端和服务器端请求两类(不考虑ajax);
相对路径
- 书写路径时,无论是哪类请求相对路径都是相对当前资源的路径
- 书写格式:直接从当前路径开始写,目录前不加任何符号;a.html html/b.html
- 相对路径在请求转发时可能会失效,因此开发中不推荐使用相对路径
- …/是返回上一级目录
绝对路径
使用绝对路径时则有两种方式,以 http:// 开头,或者以 / 开头,但是注意:只有客户端跳转才能
使用 http:// 这种方式,此时需要写出资源的完整路径;另一种以 / 开头的绝对路径,则是绝对到端口后,例如本机则是:http://localhost:8080此时则是 / 代表以上一串字符。 /helloworld/a.html → htt
p://localhost:8080/helloworld/a.html
- 浏览器中:“/”代表的是 http://主机|IP:端口
- 服务器中:“/”代表的是 http://主机|IP:端口/站点名
现在对于我们来说,只有请求转发属于服务器跳转,其他都是客户端跳转。通过观察地址栏状态也可判定跳转类型(请求类型),地址栏不变 → 服务器端跳转;地址栏改变 → 客户端跳转。
- 服务器中:“/”代表的是 http://主机|IP:端口/站点名
现在对于我们来说,只有请求转发属于服务器跳转,其他都是客户端跳转。通过观察地址栏状态也可判定跳转类型(请求类型),地址栏不变 → 服务器端跳转;地址栏改变 → 客户端跳转。