【JavaWeb】Servlet系列——转发和重定向、Servlet注解简化配置、模板方法优化项目、纯Servlet存在的问题

801 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第六天,点击查看活动详情 >>

25 在一个web应用中完成资源的跳转

在一个web应用中通过两种方式,转发重定向可以完成资源的跳转

25.1 转发和重定向的区别

25.1.1 代码上有什么区别?

  • 转发

    • // 获取请求转发器对象
      RequestDispatcher dispatcher = request.getRequestDispatcher("/dept/list");
      // 调用请求转发器对象的forward方法完成转发
      dispatcher.forward(request, response);
      
      // 合并一行代码
      request.getRequestDispatcher("/dept/list").forward(request, response);
      // 转发的时候是一次请求,不管你转发了多少次。都是一次请求。
      // AServlet转发到BServlet,再转发到CServlet,再转发到DServlet,不管转发了多少次,都在同一个request当中。
      // 这是因为调用forward方法的时候,会将当前的request和response对象传递给下一个Servlet。
      
  • 重定向

    • // 注意:路径上要加一个项目名。为什么?
      // 浏览器发送请求,请求路径上是需要添加项目名的。
      // 以下这一行代码会将请求路径“/oa/dept/list”发送给浏览器
      // 浏览器会自发的向服务器发送一次全新的请求:/oa/dept/list
      response.sendRedirect("/oa/dept/list");
      

25.1.2 形式上有什么区别?

25.1.3 转发和重定向的本质区别?

  • 转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。
  • 重定向:是浏览器完成的。具体跳转到哪个资源,是浏览器说了算。

25.1.4 使用一个例子去描述这个转发和重定向

  • 借钱(转发:发送了一次请求)
    • 杜老师没钱了,找张三借钱,其实张三没有钱,但是张三够义气,张三自己找李四借了钱,然后张三把这个钱给了杜老师,杜老师不知道这个钱是李四的,杜老师只求了一个人。杜老师以为这个钱就是张三的。
  • 借钱(重定向:发送了两次请求)
    • 杜老师没钱了,找张三借钱,张三没有钱,张三有一个好哥们,叫李四,李四是个富二代,于是张三将李四的家庭住址告诉了杜老师,杜老师按照这个地址去找到李四,然后从李四那里借了钱。显然杜老师在这个过程中,求了两个人。并且杜老师知道最终这个钱是李四借给俺的。

25.2 转发和重定向应该如何选择?

  • 如果在上一个Servlet当中向request域当中绑定了数据,希望从下一个Servlet当中把request域里面的数据取出来,使用转发机制。
  • 剩下所有的请求均使用重定向。(重定向使用较多。)

25.3 跳转的下一个资源有没有要求呢?必须是一个Servlet吗?

​ 不一定,跳转的资源只要是服务器内部合法的资源即可。包括:Servlet、JSP、HTML.....

25.4 转发会存在浏览器的刷新问题。

26 Servlet注解,简化配置

26.1 分析oa项目中的web.xml文件

  • 现在只是一个单标的CRUD,没有复杂的业务逻辑,很简单的一丢丢功能。web.xml文件中就有如此多的配置信息。如果采用这种方式,对于一个大的项目来说,这样的话web.xml文件会非常庞大,有可能最终会达到几十兆。
  • 在web.xml文件中进行servlet信息的配置,显然开发效率比较低,每一个都需要配置一下。
  • 而且在web.xml文件中的配置是很少被修改的,所以这种配置信息能不能直接写到java类当中呢?可以的。

26.2 注解式开发的优点

Servlet3.0版本之后,推出了各种Servlet基于注解式开发的。

  • 开发效率高,不需要编写大量的配置信息。直接在java类上使用注解进行标注。
  • web.xml文件体积变小了。

26.3 web.xml文件何时用?

  • 有一些需要变化的信息,还是要配置到web.xml文件中。一般都是 注解+配置文件 的开发模式。
  • 一些不会经常变化修改的配置建议使用注解。一些可能会被修改的建议写到配置文件中。

26.4 第一个注解:

jakarta.servlet.annotation.WebServlet

在Servlet类上使用:@WebServlet,WebServlet注解中有哪些属性呢?

  • name属性:用来指定Servlet的名字。等同于:

  • urlPatterns属性:用来指定Servlet的映射路径。可以指定多个字符串。

  • loadOnStartUp属性:用来指定在服务器启动阶段是否加载该Servlet。等同于:

  • value属性:当注解的属性名是value的时候,使用注解的时候,value属性名是可以省略的。

  • 注意:不是必须将所有属性都写上,只需要提供需要的。(需要什么用什么。)

  • 注意:属性是一个数组,如果数组中只有一个元素,使用该注解的时候,属性值的大括号可以省略。

26.5 注解对象的使用格式:

@注解名称(属性名=属性值, 属性名=属性值, 属性名=属性值....)

27 使用模板方法设计模式优化oa项目

27.1 oa项目存在的问题

上面的注解解决了配置文件的问题。但是现在的oa项目仍然存在一个比较臃肿的问题。

  • 一个单标的CRUD,就写了6个Servlet。如果一个复杂的业务系统,这种开发方式,显然会导致类爆炸。(类的数量太大。)
  • 怎么解决这个类爆炸问题?可以使用模板方法设计模式。

27.2 怎么解决类爆炸问题?

  • 以前的设计是一个请求一个Servlet类。1000个请求对应1000个Servlet类。导致类爆炸。
  • 可以这样做:一个请求对应一个方法。一个业务对应一个Servlet类。
  • 处理部门相关业务的对应一个DeptServlet。处理用户相关业务的对应一个UserServlet。处理银行卡卡片业务对应一个CardServlet。

28 分析使用纯粹Servlet开发web应用的缺陷

使用纯粹Servlet开发web应用,会在Servlet当中编写HTML/CSS/JavaScript等前端代码。

28.1 存在什么问题?

  • java程序中编写前端代码,编写难度大。麻烦。
  • java程序中编写前端代码,显然程序的耦合度非常高。
  • java程序中编写前端代码,代码非常不美观。
  • java程序中编写前端代码,维护成本太高。(非常难于维护)
    • 修改小小的一个前端代码,只要有改动,就需要重新编译java代码,生成新的class文件,打一个新的war包,重新发布。

28.2 怎么解决这些问题?

上面的那个Servlet(Java程序)能不能不写了,让机器自动生成。我们程序员只需要写这个Servlet程序中的“前端的那段代码”,然后让机器将我们写的“前端代码”自动翻译生成“Servlet这种java程序”。然后机器再自动将“java”程序编译生成"class"文件。然后再使用JVM调用这个class中的方法。