Servlet和Spring MVC的区别及使用说明

 更新时间:2025年01月21日 14:55:17   作者:qq_44199605  
这篇文章详细介绍了Servlet和SpringMVC的基本概念、工作原理、功能对比和应用场景,Servlet是JavaWeb开发的基础,而SpringMVC是一个基于Servlet的高级框架,提供了更强大的功能和易用性,文章通过定义、原理和示例代码,帮助读者理解这两个技术的区别与联系

前言

在 Java Web 开发中,Servlet 和 Spring MVC 是两个重要的技术。Servlet 是 Java Web 的基础组件,而 Spring MVC 是一个高级 Web 框架,建立在 Servlet 的基础之上,提供了强大的功能和易用性。

这篇文章将从定义、原理、功能对比、应用场景等多个方面,详细介绍 Servlet 和 Spring MVC,并解析它们的区别与联系。

一、什么是 Servlet

1. 定义

Servlet 是 Java Web 应用的核心组件,是一种运行在服务器上的小程序,专门用于处理客户端的 HTTP 请求并生成动态响应。

Servlet 是 Java EE 规范的一部分,定义了如何通过 Java 编写服务器端的 Web 应用。

2. 工作原理

Servlet 的核心思想是基于 请求-响应模型

  1. 客户端(通常是浏览器)发送 HTTP 请求。
  2. Web 容器(如 Tomcat)将请求路由到 Servlet。
  3. Servlet 处理请求,执行逻辑,生成并返回 HTTP 响应。

3. 核心组件

  • HttpServletRequest:表示客户端的请求对象,包含请求的所有信息(如请求参数、请求头等)。
  • HttpServletResponse:表示服务器的响应对象,包含响应的所有信息(如响应头、响应状态码、响应体等)。

4. Servlet 的生命周期

Servlet 的生命周期由 Web 容器管理,包含以下几个阶段:

  1. 初始化
    • Servlet 第一次被访问时,容器会加载 Servlet 类并调用 init() 方法完成初始化。
  2. 服务
    • 每次请求都会调用 service() 方法,根据请求的 HTTP 方法(GET、POST 等),调用对应的 doGet()doPost() 方法。
  3. 销毁
    • 在服务器关闭或卸载 Servlet 时,调用 destroy() 方法释放资源。

5. 示例代码

以下是一个简单的 Servlet 示例:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 设置响应内容类型
        resp.setContentType("text/html");
        // 返回简单的 HTML 响应
        resp.getWriter().write("<h1>Hello, Servlet!</h1>");
    }
}

二、什么是 Spring MVC

1. 定义

Spring MVC 是基于 Spring 框架的一个 Web 开发模块,提供了 MVC(Model-View-Controller) 设计模式的完整实现。

它简化了 Web 应用开发,提供了对请求映射、参数绑定、视图解析等功能的强大支持。

2. 核心思想

Spring MVC 通过 DispatcherServlet(前端控制器)将所有请求统一拦截并分发给具体的处理器(Controller),然后结合视图(View)生成响应。

3. Spring MVC 的架构

Spring MVC 的核心组件:

  1. DispatcherServlet
    • 前端控制器,负责接收和分发所有 HTTP 请求。
  2. HandlerMapping
    • 请求映射器,将 URL 映射到具体的控制器方法。
  3. Controller
    • 业务处理器,负责执行具体的逻辑。
  4. ModelAndView
    • 数据模型和视图对象,用于封装业务数据和返回的视图信息。
  5. ViewResolver
    • 视图解析器,将逻辑视图名解析为物理视图(如 JSP、Thymeleaf 页面)。
  6. View
    • 负责生成最终的响应内容(HTML、JSON 等)。

4. 工作流程

Spring MVC的工作流程

  1. 客户端发送请求。
  2. DispatcherServlet 接收请求并委托给 HandlerMapping 找到对应的 Controller 方法。
  3. Controller 方法处理请求,返回数据(Model)和视图(View)。
  4. ViewResolver 将逻辑视图名解析为物理视图。
  5. 将数据渲染到视图,生成响应并返回给客户端。

5. 示例代码

以下是一个简单的 Spring MVC 示例:

Controller 类:

@Controller
public class HelloController {
    @GetMapping("/hello")
    @ResponseBody
    public String sayHello(@RequestParam String name) {
        return "<h1>Hello, " + name + "!</h1>";
    }
}

三、Servlet 和 Spring MVC 的区别

对比维度ServletSpring MVC
定位Java Web 开发的基础技术。基于 Servlet 构建的高级 Web 框架。
设计思想直接基于 HTTP 请求-响应模型。基于 MVC(Model-View-Controller)设计模式。
开发复杂度较高,需要手动解析请求和生成响应。较低,提供自动化功能(如参数绑定、视图解析)。
功能丰富度功能较少,需要自行实现扩展(如请求映射、数据绑定)。功能丰富,内置请求映射、表单验证、异常处理等功能。
请求映射静态 URL 映射,直接通过 Web 容器配置路由。灵活的动态映射,支持正则表达式、RESTful URL 等。
视图支持需要手动拼接 HTML 或 JSP 页面。支持多种视图技术(JSP、Thymeleaf、JSON 等)。
表单验证需要手动校验参数。提供注解式校验(如 @Valid 和 @NotNull)。
异常处理需要在代码中显式捕获异常并处理。提供全局异常处理机制(如 @ControllerAdvice)。
扩展性扩展性有限,需通过 Filter 或 Listener 实现一些通用功能。提供拦截器机制,支持 AOP 和依赖注入,扩展性极强。
学习曲线入门简单,但复杂项目开发难度大。需要学习 Spring 框架基础,初学者学习曲线稍陡。
适用场景小型项目或需要直接操作 HTTP 请求的场景。中大型项目,特别是需要高扩展性和快速开发的场景。

四、Servlet 和 Spring MVC 的联系

尽管 Servlet 和 Spring MVC 在定位和功能上有所不同,但它们之间有着密切的联系:

1. 基于 Servlet 构建

  • Spring MVC 是构建在 Servlet 基础之上的高级框架。
  • Spring MVC 的核心组件 DispatcherServlet 本质上是一个 Servlet,它负责接收和分发请求。

2. Servlet 是 Spring MVC 的基础

  • Spring MVC 使用 Servlet 来处理 HTTP 请求,但屏蔽了复杂的细节,例如参数解析、请求分发等。

3. Spring MVC 依赖 Servlet 容器

  • Spring MVC 必须运行在支持 Servlet 的 Web 容器(如 Tomcat、Jetty)中。
  • Servlet 容器负责加载和管理 DispatcherServlet

五、什么时候选择 Servlet 或 Spring MVC

1. 使用 Servlet

  • 适合小型项目,功能简单。
  • 希望深入理解 Java Web 的底层原理。
  • 不需要复杂的框架支持,能够手动实现请求处理和响应。

2. 使用 Spring MVC

  • 适合中大型项目,功能复杂。
  • 需要高效开发、灵活配置和良好的扩展能力。
  • 希望享受 Spring 框架的生态系统(如 Spring Data、Spring Security 等)。

示例代码

假设我们需要构建一个简单的 Web 服务:

  • 请求路径:http://localhost:8080/hello?name=Tom
  • 返回内容:Hello, Tom!

完整 Servlet 实现

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// 使用 @WebServlet 注解映射路径 "/hello"
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

    // 初始化 Servlet(只执行一次)
    @Override
    public void init() throws ServletException {
        super.init();
        System.out.println("Servlet 初始化完成!");
    }

    // 处理 GET 请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应内容类型
        resp.setContentType("text/html;charset=UTF-8");

        // 获取请求参数
        String name = req.getParameter("name");
        if (name == null || name.isEmpty()) {
            name = "World"; // 默认值
        }

        // 返回动态响应
        resp.getWriter().write("<h1>Hello, " + name + "!</h1>");
    }

    // 销毁 Servlet(只执行一次,用于释放资源)
    @Override
    public void destroy() {
        super.destroy();
        System.out.println("Servlet 已被销毁!");
    }
}

代码优化点

  1. 注解简化配置:
    • 使用 @WebServlet 注解代替传统的 web.xml 配置。
  2. 默认参数处理:
    • 如果用户未传递参数,返回默认的 "World"。
  3. 字符编码:
    • 通过 resp.setContentType("text/html;charset=UTF-8") 设置字符编码,防止中文乱码。
  4. 日志输出:
    • init()destroy() 方法中添加日志信息,便于调试。

如何运行

  1. 将代码打包为 .war 文件,并部署到 Tomcat。
  2. 访问 URL:http://localhost:8080/hello?name=Tom
  3. 返回结果:Hello, Tom!

Spring MVC 实现

Spring MVC 的实现更加简洁且功能强大。

以下代码实现相同的功能。

Controller 类

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    // 处理 GET 请求,映射路径 "/hello"
    @GetMapping("/hello")
    @ResponseBody
    public String sayHello(@RequestParam(name = "name", required = false, defaultValue = "World") String name) {
        // 返回动态内容
        return "<h1>Hello, " + name + "!</h1>";
    }
}

Spring Boot 主类

如果使用 Spring Boot 构建项目,可以通过以下代码快速启动:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringMvcApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringMvcApplication.class, args);
    }
}

代码优化点

  1. 注解驱动开发:
    • 使用 @Controller@GetMapping 注解处理请求,简化了配置。
  2. 自动参数绑定:
    • 使用 @RequestParam 自动从请求中提取参数,同时设置默认值。
  3. 自动响应:
    • 通过 @ResponseBody 将返回的字符串直接作为响应体,省去了手动处理 HttpServletResponse
  4. Spring Boot 快速启动:
    • 使用 Spring Boot 自动化配置,无需单独部署到 Tomcat。

如何运行

  1. 将代码保存为一个 Spring Boot 应用。
  2. 运行主类 SpringMvcApplication
  3. 访问 URL:http://localhost:8080/hello?name=Tom
  4. 返回结果:Hello, Tom!

示例场景扩展

为了更好地理解 Servlet 和 Spring MVC 的应用场景,我们再扩展一个功能:根据用户输入返回 JSON 数据。

Servlet 示例(返回 JSON 数据)

import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/json")
public class JsonServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应类型为 JSON
        resp.setContentType("application/json;charset=UTF-8");

        // 获取请求参数
        String name = req.getParameter("name");
        if (name == null || name.isEmpty()) {
            name = "World";
        }

        // 构造响应数据
        Map<String, String> responseData = new HashMap<>();
        responseData.put("message", "Hello, " + name + "!");

        // 将数据转换为 JSON
        String jsonResponse = new Gson().toJson(responseData);

        // 返回 JSON 响应
        resp.getWriter().write(jsonResponse);
    }
}

Spring MVC 示例(返回 JSON 数据)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class JsonController {

    @GetMapping("/json")
    public Map<String, String> sayHello(@RequestParam(name = "name", required = false, defaultValue = "World") String name) {
        // 构造响应数据
        Map<String, String> response = new HashMap<>();
        response.put("message", "Hello, " + name + "!");
        return response;
    }
}

doGet()doPost()service() 的区别

特性service()doGet()doPost()
定位通用方法,用于处理所有 HTTP 请求类型。专门用于处理 HTTP GET 请求。专门用于处理 HTTP POST 请求。
调用方式由 Web 容器直接调用。由 service() 方法根据 HTTP 请求方法分发调用。由 service() 方法根据 HTTP 请求方法分发调用。
实现目的自动分发请求到对应的 doXxx() 方法。处理只读请求(如查询数据)。处理数据提交(如表单、文件上传)。
开发者重写很少被重写,通常由 Web 容器托管。常被重写以处理 GET 请求。常被重写以处理 POST 请求。
请求语义无特定语义,作为分发入口。遵循 HTTP GET 请求的语义(幂等)。遵循 HTTP POST 请求的语义(非幂等)。

总结

区别

  • Servlet 是 Java Web 开发的基础技术,提供了直接操作 HTTP 请求和响应的能力,适合小型项目或需要深入了解底层原理的场景。
  • Spring MVC 是一个基于 Servlet 的高级 Web 框架,提供了大量的自动化功能和开发便利性,适合中大型项目。

联系

  • Spring MVC 是建立在 Servlet 技术之上的框架,它通过 DispatcherServlet 实现请求的接收和分发。
  • Servlet 是 Spring MVC 的基础,但 Spring MVC 封装了许多底层细节,使开发更高效。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java Config下的Spring Test几种方式实例详解

    Java Config下的Spring Test几种方式实例详解

    这篇文章主要介绍了Java Config下的Spring Test方式实例代码的相关资料,需要的朋友可以参考下
    2017-05-05
  • 详解利用spring-security解决CSRF问题

    详解利用spring-security解决CSRF问题

    这篇文章主要介绍了详解利用spring-security解决CSRF问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • SpringBoot使用Scheduling实现定时任务的示例代码

    SpringBoot使用Scheduling实现定时任务的示例代码

    Spring Boot提供了一种方便的方式来实现定时任务,即使用Spring的@Scheduled注解,通过在方法上添加@Scheduled注解,我们可以指定方法在何时执行,本文我们就给大家介绍一下SpringBoot如何使用Scheduling实现定时任务,需要的朋友可以参考下
    2023-08-08
  • Spring(一):IOC如何推导和理解

    Spring(一):IOC如何推导和理解

    下面小编就为大家带来一篇详谈Spring对IOC的理解(推荐篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-07-07
  • 关于Java中Json的各种处理

    关于Java中Json的各种处理

    这篇文章主要介绍了关于Java中Json的各种处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • SpringCloud实现全链路灰度发布的示例详解

    SpringCloud实现全链路灰度发布的示例详解

    灰度发布是指在软件或服务发布过程中,将新版本的功能或服务以较小的比例引入到生产环境中,仅向部分用户或节点提供新功能的一种发布策略,下面我们就来学习一下SpringCloud如何实现全链路灰度发布
    2023-11-11
  • 超详细讲解Java异常

    超详细讲解Java异常

    Java 异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。本文超详细讲解了Java异常,感兴趣的小伙伴可以参考一下这篇文章
    2021-09-09
  • Javacv使用ffmpeg实现音视频同步播放

    Javacv使用ffmpeg实现音视频同步播放

    这篇文章主要介绍了Javacv使用ffmpeg实现音视频同步播放,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • springboot调用webservice-soap接口的实现

    springboot调用webservice-soap接口的实现

    接口协议目前广泛使用的有http协议和RPC协议和webservice,本文主要介绍了springboot调用webservice-soap接口的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Spring Boot学习入门之AOP处理请求详解

    Spring Boot学习入门之AOP处理请求详解

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,下面这篇文章主要给大家介绍了关于Spring Boot学习入门之AOP处理请求的相关资料,需要的朋友可以参考下。
    2017-09-09

最新评论