Web框架的前生今世 从Servlet到Spring MVC到Spring boot

背景

上世纪90年代,随着Internet和浏览器的飞速发展,基于浏览器的B/S模式随之火爆发展起来。最初,用户使用浏览器向WEB服务器发送的请求都是请求静态的资源,比如html、css等。 但是可以想象:根据用户请求的不同动态的处理并返回资源是理所当然必须的要求。

servlet的定义

Servlet is a technology which is used to create a web application. servlet是一项用来创建web application的技术。 Servlet is an API that provides many interfaces and classes including documentation. servlet是一个提供很多接口和类api及其相关文档。 Servlet is an interface that must be implemented for creating any Servlet.servlet是一个接口,创建任何servlet都要实现的接口。 Servlet is a class that extends the capabilities of the servers and responds to the incoming requests. It can respond to any requests. servlet是一个实现了服务器各种能力的类,对请求做出响应。它可以对任何请求做出响应。 Servlet is a web component that is deployed on the server to create a dynamic web page.servlet是一个web组件,部署到一个web server上(如tomcat,jetty),用来产生一个动态web页面。

servlet的历史

web框架的前生今世--从servlet到spring mvc到spring boot

web Container

web容器也叫servlet容器,负责servlet的生命周期,映射url请求到相应的servlet。

A web container (also known as a servlet container;[1] and compare "webcontainer"[2]) is the component of a web server that interacts with Java servlets. A web container is responsible for managing the lifecycle of servlets, mapping a URL to a particular servlet and ensuring that the URL requester has the correct access-rights.A web container handles requests to servlets, JavaServer Pages (JSP) files, and other types of files that include server-side code. The Web container creates servlet instances, loads and unloads servlets, creates and manages request and response objects, and performs other servlet-management tasks.A web container implements the web component contract of the Java EE architecture. This architecture specifies a runtime environment for additional web components, including security, concurrency, lifecycle management, transaction, deployment, and other services.

常见的web容器如下:

web框架的前生今世--从servlet到spring mvc到spring boot

在web容器中,web应用服务器的结构如下:

web框架的前生今世--从servlet到spring mvc到spring boot

1.普通servlet实现页面访问

web框架的前生今世--从servlet到spring mvc到spring boot

1.1 实例1:使用web.xml实现一个http服务

实现一个简单的servlet

package com.howtodoinjava.servlets;   import java.io.IOException; import java.io.PrintWriter;   import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   public class MyFirstServlet extends HttpServlet {    private static final long serialVersionUID = -1915463532411657451L;    @Override  protected void doGet(HttpServletRequest request,  HttpServletResponse response) throws ServletException, IOException  {  response.setContentType("text/html;charset=UTF-8");  PrintWriter out = response.getWriter();  try {  // Write some content  out.println("<html>");  out.println("<head>");  out.println("<title>MyFirstServlet</title>");  out.println("</head>");  out.println("<body>");  out.println("<h2>Servlet MyFirstServlet at " + request.getContextPath() + "</h2>");  out.println("</body>");  out.println("</html>");  } finally {  out.close();  }  }    @Override  protected void doPost(HttpServletRequest request,  HttpServletResponse response) throws ServletException, IOException {  //Do some other work  }    @Override  public String getServletInfo() {  return "MyFirstServlet";  } } 

web.xml配置servlet

/MyFirstServlet MyFirstServlet com.howtodoinjava.servlets.MyFirstServlet MyFirstServlet /MyFirstServlet

1.2 编程方式实现一个http服务请求

不需要xml

package com.journaldev.first; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /**  * Servlet implementation class FirstServlet  */ @WebServlet(description = "My First Servlet", urlPatterns = { "/FirstServlet" , "/FirstServlet.do"}, initParams = {@WebInitParam(name="id",value="1"),@WebInitParam(name="name",value="pankaj")}) public class FirstServlet extends HttpServlet {  private static final long serialVersionUID = 1L;  public static final String HTML_START="<html><body>";  public static final String HTML_END="</body></html>";    /**  * @see HttpServlet#HttpServlet()  */  public FirstServlet() {  super();  // TODO Auto-generated constructor stub  }  /**  * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)  */  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  PrintWriter out = response.getWriter();  Date date = new Date();  out.println(HTML_START + "<h2>Hi There!</h2><br/><h3>Date="+date +"</h3>"+HTML_END);  }  /**  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)  */  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  // TODO Auto-generated method stub  } } 

2.spring mvc实现页面访问

2.1 web.xml方式

web框架的前生今世--从servlet到spring mvc到spring boot

示例:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  version="2.5">  <display-name>Gradle + Spring MVC Hello World + XML</display-name>  <description>Spring MVC web application</description>  <!-- For web context -->  <servlet>  <servlet-name>hello-dispatcher</servlet-name>  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  <init-param>  <param-name>contextConfigLocation</param-name>  <param-value>/WEB-INF/spring-mvc-config.xml</param-value>  </init-param>  <load-on-startup>1</load-on-startup>  </servlet>  <servlet-mapping>  <servlet-name>hello-dispatcher</servlet-name>  <url-pattern>/</url-pattern>  </servlet-mapping>  <!-- For root context -->  <listener>  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>  <context-param>  <param-name>contextConfigLocation</param-name>  <param-value>/WEB-INF/spring-core-config.xml</param-value>  </context-param> </web-app> 

2.2 编码方式

public class MyWebAppInitializer implements WebApplicationInitializer {    @Override  public void onStartup(ServletContext container) {  // Create the 'root' Spring application context  AnnotationConfigWebApplicationContext rootContext =  new AnnotationConfigWebApplicationContext();  rootContext.register(AppConfig.class);    // Manage the lifecycle of the root application context  container.addListener(new ContextLoaderListener(rootContext));    // Create the dispatcher servlet's Spring application context  AnnotationConfigWebApplicationContext dispatcherContext =  new AnnotationConfigWebApplicationContext();  dispatcherContext.register(DispatcherConfig.class);    // Register and map the dispatcher servlet  ServletRegistration.Dynamic dispatcher =  container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));  dispatcher.setLoadOnStartup(1);  dispatcher.addMapping("/");  }    } 

内部实现

web框架的前生今世--从servlet到spring mvc到spring boot

3.spring boot

继承了spring mvc的框架,实现SpringBootServletInitializer

package com.mkyong; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; @SpringBootApplication public class SpringBootWebApplication extends SpringBootServletInitializer {  @Override  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  return application.sources(SpringBootWebApplication.class);  }  public static void main(String[] args) throws Exception {  SpringApplication.run(SpringBootWebApplication.class, args);  } } 

然后controller

package com.mkyong; import java.util.Map; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class WelcomeController {  // inject via application.properties  @Value("${welcome.message:test}")  private String message = "Hello World";  @RequestMapping("/")  public String welcome(Map<String, Object> model) {  model.put("message", this.message);  return "welcome";  } } 

总结:

1.servlet的本质没有变化,从web框架的发展来看,web框架只是简化了开发servlet的工作,但还是遵循servlet规范的发展而发展的。

2.servlet的历史发展,从配置方式向编程方式到自动配置方式发展

3.spring mvc框架的分组:root和child(可以有多个dispatcherservlet),多个child可以共享root,child直接不共享

参考文献:

【1】https://en.wikipedia.org/wiki/Web_container

【2】https://baike.baidu.com/item/servlet/477555?fr=aladdin

【3】https://www.javatpoint.com/servlet-tutorial

【4】https://www.journaldev.com/1854/java-web-application-tutorial-for-beginners#deployment-descriptor

【5】https://blog.csdn.net/qq_22075041/article/details/78692780

【6】http://www.mkyong.com/spring-mvc/gradle-spring-mvc-web-project-example/

【7】http://www.mkyong.com/spring-boot/spring-boot-hello-world-example-jsp/