背景知识:
- java算是一门彻底的面向对象的编程语言,对于它的学习即使我们在日常工作中可能不会使用到,但是可以帮助我们更好的理解和践行面向对象思想。
- 本文基于Tomcat8.5.39版本
我们先来聊聊重定向吧,接触过web开发的小伙伴都知道重定向其实是页面跳转的一种方式,原理就是借助http响应头Location的值来完成的。重定向的原理:浏览器通过url访问服务器的资源,服务器接收到请求时,通过设置状态码为302,响应头Location为目标url,并将响应返回给浏览器,浏览器获取到响应后再根据Location的值,再次发送http请求,访问目标url。具体的效果如下:
细心的小伙伴可能发现:重定向其实是两次http请求,并且浏览器地址栏的url也会随之发生变化。那么在javaweb中如何实现重定向呢?
方式一:
resp.setStatus(302); // 设置状态码
resp.setHeader("location", "/javaweb/test2"); // 重定向的目标url
方式二:使用tomcat封装好的方法
resp.sendRedirect("/javaweb/test2");
对于上面的代码可以优化:(动态获取虚拟目录)
resp.sendRedirect(request.req.getContextPath() + "/test2")
注意:
resp是tomcat提供的HttpServletResponse对象
request是tomcat提供的HttpServletRequest对象
/javaweb是我本机设置的虚拟目录
接下来我们谈谈请求的转发。请求转发有点像方法的调用,当服务器接收到浏览器某个ur请求时,发现对应的Servlet处理不了这个请求,这时候服务器可以直接将这个请求分发给当前web应用程序中可以处理该请求的Servlet,而不需要将目标url以响应的方式给浏览器,再由浏览器去请求目标url进行处理。接下来简单介绍一下javaweb实现请求转发的过程:
首先准备两个测试的Servlet
@WebServlet("/test1")
public class Test1Controller extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Test1Controller控制器的doGet方法被访问了~");
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/test2");
requestDispatcher.forward(req, resp);
}
}
@WebServlet("/test2")
public class Test2Controller extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Test2Controller控制器被访问了~");
}
}
然后我们在浏览器中访问:
接下来我们看看控制台的打印输出:
通过上面的介绍我们可以轻松的得出请求转发和重定向的区别:
1. 重定向是两次http请求而转发实际只有一次http请求
2. 由第一点可以得出,重定向的浏览器地址栏url会变化,而转发则不会
请求转发有一个注意事项:只能转发给同一个web应用程序处理。怎么理解呢,查看下面的代码:
// 以下转发是不允许的,会报404的错误
RequestDispatcher requestDispatcher = req.getRequestDispatcher("https://www.baidu.com/");
requestDispatcher.forward(req, resp);
//但是重定向可以指向任意服务器
response.sendRedirect("https://www.baidu.com/");
最后,细心的小伙伴可能发现了,我们在设置重定向地址的时候添加了虚拟目录而转发却没有设置:
重定向的代码:
resp.sendRedirect(req.getContextPath() + "/test2");
转发的代码:
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/test2");
requestDispatcher.forward(req, resp);
这是因为:重定向是交由浏览器去执行的,换句话说这个地址是交给浏览器处理的,不指定虚拟目录会导致404,而转发只能转发给当前web应用程序中的Servlet处理,换句话说,转发的地址和当前请求的地址一定是在同一个虚拟目录中的。
以上就是今天分享的全部啦,感谢阅读。