转发 && 重定向
作用
在Servlet中实现页面的跳转有两种方式:转发和重定向
页面的跳转:转发
1.转发的原理 2.转发的方法 3.疑问 能否在FirstServlet中保存值到请求域中,在另一个SecondServlet中打印出来?
什么是转发
概念:由服务器端进行的页面跳转
原理图
转发的方法
1.得到转发器:RequestDispatcher request.getRequestDispatcher("/跳转的地址") ——》参数是要跳转的地址 2.实现转发:转发器对象.forward(request,response) 我们通常写成一句话: request.getRequestDispatcher("/跳转的地址").forward(request,response);
转发的案例
需求
实现从FirstServlet中转发到SecondServlet
步骤
FirstServlet向请求域中添加了一个键和值,转发给SecondServlet SecondServlet就从请求域中取出键和值,打印到浏览器上。
效果
代码
FirstServlet
package com.octuple.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /**与请求域相关的方法*/ @WebServlet(name = "FirstServlet", urlPatterns = "/first") public class FirstServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.print("这是First<br/>");//向请求域中添加键和值request.setAttribute("msg","你好");String msg = (String) request.getAttribute("name");//从请求域中取出值out.print("消息:" + msg + "<br/>");out.print("<hr/>"); //从请求域中取出值,直接输出Object对象out.print("消息:" + request.getAttribute("msg") + "<br/>"); System.out.println("这是first");//开始转发,参数是:要跳转到的地址request.getRequestDispatcher("/second").forward(request, response);} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);} }
SecondServlet
package com.octuple.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; //从请求域中取出值 @WebServlet(name = "SecondServlet", urlPatterns = "/second") public class SecondServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.print("这是Second,从请求域中取出First中的值:" + request.getAttribute("msg"));} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);} }
转发的特点
1.地址栏不发生变化,显示的是上一个页面的地址
2.请求次数:只有1次请求
3.根目录:http://localhost:8080/项目地址/,包含了项目的访问地址
4.请求域中数据不会丢失
5.转发只能访问当前服务器下的资源
页面的跳转:重定向
1.重定向原理 2.重定向的方法
什么是重定向
概念:由浏览器端进行的页面跳转
原理图
重定向方法
1.设置状态码为302 response.setStatus(302); 2.设置响应头 response.setHeader("localtion","/跳转的地址"); 3.我们通常写成一句话: response.sendRedirect("/跳转的地址");
重定向的案例
需求
实现从FirstServlet中转发到SecondServlet
步骤
在FirstServlet中向请求域中添加键和值 使用重定向到SecondServlet,在SecondServlet中看能否取出请求域的值
效果
代码
FirstServlet
package com.octuple.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /**与请求域相关的方法*/ @WebServlet(name = "FirstServlet**", urlPatterns = "/first") public class FirstServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.print("这是First<br/>");//向请求域中添加键和值request.setAttribute("msg","你好");String msg = (String) request.getAttribute("msg");//从请求域中取出值out.print("消息:" + msg + "<br/>"); //从请求域中取出值,直接输出Object对象out.print("消息:" + request.getAttribute("msg") + "<br/>"); System.out.println("这是First");//开始转发,参数是:要跳转到的地址//request.getRequestDispatcher("/second").forward(request, response); //使用重定向response.sendRedirect("/second");} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);} }
SecondServlet
package com.octuple.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; //从请求域中取出值 @WebServlet(name = "SecondServlet", urlPatterns = "/second") public class SecondServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.print("这是Second,从请求域中取出First中的值:" + request.getAttribute("msg"));} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);} }
重定向的特点
1.地址栏:显示新的地址
2.请求次数:2次
3.根目录:http://localhost:8080/ 没有项目的名字【重定向不需要写项目的名字】
4.请求域中的数据会丢失,因为是2次请求
5.重定向可以访问其他站点(服务器)的资源
总结:
1.问:什么时候使用转发,什么时候使用重定向?
如果要保留请求域中的数据,使用转发,否则使用重定向。
2.以后访问数据库,增删改使用重定向,查询使用转发。
问:转发或重定向后续的代码是否还会运行?
无论转发或重定向后续的代码都会执行
3.具体分析:
①请求转发:在地址栏处请求地址没有发生改变,还是初次发出请求的地址
请求重定向:在地址栏处请求地址发生改变
②请求转发:在最终的servlet中,request对象和中转的request是同一个对象
请求重定向:在最终的servlet中,若quest对象和中转的request不是同一个对象。
应用场景:如果在进行查询操作的时候,我们应该使用转发操作,速度快
如果在进行增、删、改操作的时候,我们应该使用重定向操作,如果此种情况采用转发进行操作,在操作前后URL地址栏信息不发生改变,仍然是修改的控制器,如果此时再对当前页面刷新的话,就会重新发送一次请求对数据进行修改,这也就是有的人在刷新一次页面就增加一条数据的原因。
后台接口中是否有return语句分析
通过以上分析得知,我们在增、删、改操作中使用重定向【因为此时我们需要保存请求域中的数据】,在查询操作中我们使用转发操作【因为此时我们不需要保存请求域中的数据】,那么由此分析后台接口中增、删、改操作并不需要有返回值,所以没有return语句,进而言之,查询操作中需要有返回值,所以使用return语句