Java Web 起源于上世纪 90 年代,随着网络和浏览器的飞速发展,Java 为应对动态处理网页的需求,推出了 Servlet 技术。
1. Servlet 出现之前
在 Servlet 出现之前,用户请求主要是静态资源,如 html、css 等。此时的网络主要是一系列静态内容的集合,服务器通过保持一系列 html 脚本来响应用户的请求。早期的 web 应用较为简单,确立了 request(代表请求)和 response(代表回应)这两个重要对象。
在 web site 向 web application 发展的过程中,出现了 applet。例如当年风靡校园的网易聊天室就是采用了 applet 构建的,它给静态页面带来了动态交互的可能。
2. Servlet 时代
- 纯 Servlet 开发:Servlet 是 Java 技术中最早的 Web 解决方案。
Servlet 看起来像是通常的 Java 程序,命名为 Service+Applet,即服务小程序。它可以处理来自客户端的请求,并生成响应。在 Servlet 中可以通过输出 Html 等语句来实现页面的样式和输出,实现数据的动态功能。然而,表现、逻辑、控制、业务全部混在 Servlet 类中,编程繁琐,输出 HTML 代码麻烦。
例如:
public void doGet(HttpServletRequest request, HttpServletResponse) throws IOException, ServletException {
response.setContentType("text/html;charset=gb2312");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Hello World!</title></head>");
out.println("<body>");
out.println("<p>Hello World!</p>");
out.println("</body>");
out.println("</html>");
}
这样就动态生成了一个内容为 Hello World! 的 HTML 页面在浏览器上显示。但这种方式存在很多问题,如 servlet 代码有大量冗余代码,开发 servlet 必须精通网页前端和美工,所有业务逻辑、页面跳转、样式表现全部混杂在同一个类中,维护困难。
二、JSP 的诞生
- Sun 公司借鉴微软的 asp,推出了 JSP 技术,采用 HTML 语言直接生成界面,可嵌入 Java 代码,但存在代码维护困难的问题。
1. 纯 JSP 开发
在 JSP 诞生初期,出现了纯 JSP 开发的方式。示例代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse) throws IOException, ServletException {
response.setContentType("text/html;charset=gb2312");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Hello World!</title></head>");
out.println("<body>");
out.println("<p>Hello World!</p>");
out.println("</body>");
out.println("</html>");
}
这段代码展示了在 HTML 代码中写 Java 代码的方式,通过在 Servlet 中输出 HTML 语句来生成页面。然而,这种方式存在很多问题,如代码维护困难,表现、逻辑、控制、业务全部混在 Servlet 类中,编程繁琐,输出 HTML 代码麻烦。
2. JSP+JavaBean(Model1)
JSP 负责表现层和控制层,JavaBean 负责模型层,但高度耦合,后期维护困难。
JSP+JavaBean 模式适合小规模 web 开发,体现在其轻巧性,也就是更轻量级一些。在这种模式中,JSP 除了负责部分流程的控制外,大部分用来进行页面的显示,而 JavaBean 则负责事务逻辑层和数据层的工作。
JSP 和 JavaBean 模型充分利用了 JSP 技术易于开发动态网页的特点,页面显示层的任务由 JSP(但它也含事物逻辑层的内容)承担,JavaBean 主要负责事务逻辑层和数据层的工作。JSP 和 JavaBean 模型依靠几个 JavaBean 组件实现具体的应用功能,生成动态内容,最大的特点就是简单。
但是这种模式也有很多缺点,比如 HTML 和 JAVA 强耦合在一起,给页面设计带来极大困难,也给阅读代码、理解程序带来干扰。极难维护与扩展,在 JSP 页面中直接嵌入访问数据的代码及 SQL 语句,会使数据库的任何改动都必须打开所有的 JSP 页面进行维修,改动工作量非常大。不方便调试,业务逻辑与 HTML 代码,甚至 JavaScript 代码强耦合在一起,极难定位错误。
JSP+JavaBean 的优点也很明显,比如纯净的 JSP 页面,将业务逻辑和数据库操作从 JSP 页面中剥离出来。可重用的组建,设计良好的 JavaBean 可以重用,可重用的 JavaBean 可以大大减少开发人员的工作量,加快开发进度。方便进行调试,因为复杂的操作都封装在一个或多个 JavaBean 中,错误比较容易定位。易维护易扩展,系统的升级或者更改往往集中在一组 JavaBean 中,而不用编辑所有的 JSP 页面。
三、Servlet+JSP+JavaBean(Model2 时代)
在 Servlet+JSP+JavaBean(Model2 时代),JSP 作为视图负责展示页面,Servlet 作为控制器承担接收请求、调用业务逻辑和控制页面跳转等任务,JavaBean 负责业务模型的处理。然而,这种模式下的 JavaBean 往往会显得过于臃肿,并不能完全符合标准的 MVC 设计模式。
在 Model2 中,虽然通过明确的分工将视图、控制器和业务模型进行了分离,但是 JavaBean 需要承担大量的业务逻辑处理以及可能的数据持久化等任务。这使得 JavaBean 中包含了过多的代码和功能,导致其结构复杂,难以维护和扩展。例如,在处理复杂业务逻辑时,JavaBean 可能会不断地添加新的方法和属性,使得其规模逐渐增大,变得难以管理。
与标准的 MVC 设计模式相比,Model2 在一定程度上实现了视图、控制器和模型的分离,但 JavaBean 的过度膨胀使得模型层不够纯粹和清晰。在标准的 MVC 设计模式中,模型层应该专注于业务逻辑的处理,具有清晰的职责和结构。而在 Model2 中,JavaBean 不仅要处理业务逻辑,还可能涉及到与数据库的交互、数据的存储和获取等任务,这使得它的职责不够明确,影响了整个系统的可维护性和可扩展性。
四、框架阶段
在 Java Web 的发展过程中,框架阶段的出现解决了许多前期存在的问题,极大地提高了开发效率和代码的可维护性。
- 存在问题:jsp 页面中嵌入很多 java 代码,结构乱;servlet 过多,不易集中管理。
1. Struts 的出现
2001 年 6 月,Struts1.0 出现,针对 JSP 和 Servlet 存在的问题提供了有效的解决方案。
-
推出 struts 标签,使 jsp 中没有 Java 代码,结构清晰,功能强大。例如,原本 JSP 页面中可能会嵌入大量的 Java 代码来实现各种功能,现在通过 Struts 标签,可以直接使用标签来代替 Java 代码,使得页面更加简洁易读。
-
提供 Action 类代替 servlet,这个 Action 类具有 servlet 的功能,并且能够进行一些请求过滤和自动转码功能。Action 类的出现,使得 Servlet 的管理更加集中,减少了 Servlet 数量过多带来的转向频繁和配置不易集中管理的问题。
2. Spring 的出现
Spring 框架的出现主要是为了解决程序耦合性问题。
- 解决程序耦合性问题,具有 IOC(控制反转)和 AOP(面向切面的编程)两大功能。IOC 即当一个类中想要调用另外一个类的对象时,不需要再通过 new 关键字来创建,而是由 Spring 框架来负责创建、分配和管理,从而降低了程序中的耦合性。AOP 可以用来做一些日志的打印和输出,用于提示程序执行过程中的一些具体信息等。
3. SpringMVC 的出现
SpringMVC 的出现是为了进一步优化开发过程。
- 通过 “基于注解” 的方式代替 struts,降低了.xml 文件的配置复杂度。原本 Struts 和 Spring 的整合,每一个 bean 都要在 Spring 中注册,每一个 URL 都要在 struts 配置文件中配置,当 bean 很多和 URL 对应的请求很多的时候,配置文件会非常庞大,配置起来费力。而 SpringMVC 通过基于注解的方式,很多配置信息放在了 Controller 类中配置,减少了.xml 文件的配置量,提高了开发效率。
4. Springboot 的出现
- 设计初衷是简化 Spring 应用的初始搭建和开发过程。Spring Boot 并不是像 Spring 和 SpringMVC 这种全新的、实现某个功能的应用框架,而是一种用于简化 Spring 应用开发,实现应用快速开发迭代的解决方案。它主要解决了基于 SpringMVC 开发 Java Web 应用存在的开发效率低的问题,以及解决需要依赖 Tomcat 进程来运行 Java Web 应用的问题,最终简化了 Spring 应用的搭建、开发和维护。例如,通过约定优于配置的理念和 starter 包,将实现某个功能的多个相关 jar 包打包到一个更大的 jar 包中,应用只需引入对应的 starter 包,而不需要一个个地引入多个功能 jar 包来简化包的配置,同时由 SpringBoot 统一管理 jar 包的版本,避免了包的兼容和类冲突问题。此外,Spring Boot 实现了一种自动配置机制,根据应用当前引入的 starter 包来自动创建对应功能的 bean 对象,使得在应用中直接使用即可,大大提高了开发效率。