【Dispatcher】请求转发

谁践踏了优雅 2023-10-01 20:21 125阅读 0赞

介绍

在前面,我们学习的一次请求对应的就是一个Servlet,但是当我们的功能比较复杂时,一个Servlet很难满足我们的需求,往往需要几个Servlet进行协作完成,于是便有了请求转发[Dispatcher],Dispathcer可以实现请求转发功能,并且携带将本次的Request和Respond携带到下一个Servlet,实现一次请求访问多个Servlet,完成复杂的功能。

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBA5LiN5pyN6L6T55qE5bCR5bm0_size_20_color_FFFFFF_t_70_g_se_x_16

注意,上面只是一个简单示意图,实际上请求转发不是Servlet直接调用下一个Servlet,而是先返回tomcat,tomcat再调用下一个Servlet!!!


说明

  • 请求转发是当Servlet被调用时,如果需要请求转发,那么这个Servlet会通知服务器,然后服务器来调用另外的Servlet
  • Dispathcer是一个对象,这个对象是HttpServletRequest提供的,我们可以通过getDispathcer()方法获取对象,得到对象后我们就可以进行转发(通过forward方法),转发时把这次的request和response带上,转发对象的request和response和当前Servlet的request,response是一样的。
  • HttpServletRequest是一个域对象,当我们需要将某些数据转发给下一个Servlet时,我们可以使用HttpServletRequest的setAttribute(String,Object)方法设置属性,而转发的Servlet通过getAttribut(String)方法就可以得到数据。

练习

我们使用请求转发来做一个练习,定义2个Servlet,一个Servlet实现用户的校验工作,一个实现显示的工作,这样每个Servlet就分工明确了,各司其职,通过请求转发来实现他们之间的调用。我们再创建一个登录页面,根据登录用户的不同来显示不同的页面。代码如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>请求转发练习</title>
  6. </head>
  7. <body>
  8. <form action="http://localhost:8080/servlet/check" method="post">
  9. 用户名:<input type="text" name="username"><br>
  10. 密 码:<input type="password" name="password"><br>
  11. <input type="submit" value="登录">
  12. </form>
  13. </body>
  14. </html>
  15. import javax.servlet.*;
  16. import javax.servlet.annotation.WebServlet;
  17. import javax.servlet.http.*;
  18. import java.io.IOException;
  19. @WebServlet("/check")
  20. public class CheckServlet extends HttpServlet {
  21. @Override
  22. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  23. //得到提交的用户名
  24. String username = request.getParameter("username");
  25. //如果提交的用户名是root,我们就认为这是一个管理员
  26. if ("root".equals(username)){
  27. //设置域属性
  28. request.setAttribute("identity","管理员");
  29. }else {
  30. request.setAttribute("identity","普通用户");
  31. }
  32. //得到Dispatcher对象
  33. //getRequestDispatcher(String s);这个方法里面的参数填的是要转发的url
  34. RequestDispatcher dispatcher = request.getRequestDispatcher("/show");
  35. //进行转发,并把request和response带上
  36. dispatcher.forward(request,response);
  37. }
  38. @Override
  39. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  40. this.doGet(request,response);
  41. }
  42. }
  43. import javax.servlet.*;
  44. import javax.servlet.annotation.WebServlet;
  45. import javax.servlet.http.*;
  46. import java.io.IOException;
  47. import java.io.PrintWriter;
  48. @WebServlet("/show")
  49. public class ShowServlet extends HttpServlet {
  50. @Override
  51. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  52. //得到用户名
  53. String username = request.getParameter("username");
  54. //得到身份
  55. String identity = (String)request.getAttribute("identity");
  56. //设置响应的MIME和编码
  57. response.setContentType("text/html;charset=utf-8");
  58. //得到输出流
  59. PrintWriter writer = response.getWriter();
  60. //写回数据
  61. writer.write("<h1>亲爱的:"+username+" 欢迎登录</h1>");
  62. writer.write("<h1>您现在是"+identity+"登录</h1>");
  63. //关闭流
  64. writer.flush();
  65. writer.close();
  66. }
  67. @Override
  68. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  69. this.doGet(request,response);
  70. }
  71. }

现在,我们来到登录页面进行测试,我们首先在用户名和密码都输入tom进行登录

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBA5LiN5pyN6L6T55qE5bCR5bm0_size_17_color_FFFFFF_t_70_g_se_x_16

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBA5LiN5pyN6L6T55qE5bCR5bm0_size_20_color_FFFFFF_t_70_g_se_x_16 1

发现登录后显示我是一个普通用户,接下来,我们再使用root进行登录

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBA5LiN5pyN6L6T55qE5bCR5bm0_size_17_color_FFFFFF_t_70_g_se_x_16 1

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBA5LiN5pyN6L6T55qE5bCR5bm0_size_20_color_FFFFFF_t_70_g_se_x_16 2

发现登录后显示我们是管理员登录,到此,我们就实现了这个功能,一个Servlet只实现一个功能,通过请求转发来实现不同Servlet之间的调用。


注意事项

  • 我们使用请求转发,不会导致游览器地址栏的url发生变化
  • 在请求转发中,虽然调用了多个Servlet,但是仍然是一次Http请求
  • 可以转发到WEB-INF目录下
  • 不能转发到当前这个Web资源外面去
  • 多个Servlet之间可以共享request的数据

发表评论

表情:
评论列表 (有 0 条评论,125人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JavaWeb_请求转发

    请求的转发和重定向:   1)本质区别:请求的转发只发出一次请求,而重定向则发出来两次请求。 具体: ①请求的转发:地址栏是初次发出请求的地址     请求的重定向:

    相关 Nginx请求转发

    1.简介​​​​​​ Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,