Spring MVC 知识点全解析

Spring MVC 知识点全解析

Spring MVC 是一个基于 Java 的请求驱动的 Web 框架,属于 Spring 框架的一部分,广泛用于构建企业级 Web 应用程序。本文将详细阐述 Spring MVC 的核心知识点,包括其工作原理、关键组件、配置、请求处理、数据绑定、异常处理等。

1. Spring MVC 概述

1.1 什么是 Spring MVC

Spring MVC(Model-View-Controller)是一个基于 MVC 设计模式的框架,它将应用程序分为三部分:

  • Model:表示应用程序的数据和业务逻辑。
  • View:负责呈现数据的用户界面。
  • Controller:处理用户的请求并返回模型和视图。

1.2 特点

  • 灵活性:支持多种视图技术(如 JSP、Thymeleaf、FreeMarker 等)。
  • 松耦合:通过接口和注解,组件间的耦合度较低。
  • 强大的数据绑定:支持复杂对象的自动数据绑定和校验。
  • 丰富的扩展性:可以通过拦截器、过滤器等方式扩展功能。

2. Spring MVC 的工作原理

Spring MVC 的工作流程可以总结为以下几个步骤:

  1. 请求到达 DispatcherServlet:所有请求首先到达 DispatcherServlet,它是 Spring MVC 的前端控制器,负责请求的分发。
  2. 处理请求DispatcherServlet 会将请求委托给相应的 HandlerMapping,根据请求的 URL 找到对应的控制器。
  3. 调用控制器DispatcherServlet 调用对应的控制器方法,控制器处理请求并返回模型和视图。
  4. 返回视图:返回的视图名会被 ViewResolver 解析为实际的视图对象。
  5. 渲染视图:视图被渲染并返回给用户。

3. 核心组件

3.1 DispatcherServlet

DispatcherServlet 是 Spring MVC 的核心组件,它负责请求的接收、分发和处理。

3.2 HandlerMapping

HandlerMapping 是用来将请求映射到相应的控制器的接口。Spring MVC 提供了多种实现方式,如 RequestMappingHandlerMapping

3.3 Controller

控制器是处理用户请求的核心部分,负责处理业务逻辑并返回视图。可以使用 @Controller 注解来定义控制器。

3.4 ModelAndView

ModelAndView 是用于封装模型和视图的对象。控制器返回一个 ModelAndView 对象,包含模型数据和视图名。

3.5 ViewResolver

ViewResolver 负责将逻辑视图名解析为实际的视图实现。常用的实现有 InternalResourceViewResolverThymeleafViewResolver 等。

3.6 Interceptor

拦截器用于在请求处理之前和之后执行一些逻辑,如权限验证、日志记录等。可以通过实现 HandlerInterceptor 接口来定义。

4. Spring MVC 配置

4.1 XML 配置

web.xml 中配置 DispatcherServlet

<servlet>
    <servlet-name>dispatcherservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <load-on-startup>1load-on-startup>
servlet>

<servlet-mapping>
    <servlet-name>dispatcherservlet-name>
    <url-pattern>/url-pattern>
servlet-mapping>

dispatcher-servlet.xml 中配置视图解析器和组件扫描:

<context:component-scan base-package="com.example.controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
bean>

4.2 注解配置

使用注解配置更加简洁,通常在主类中使用 @EnableWebMvc 开启 Spring MVC 支持,并通过 @ComponentScan 扫描控制器。

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller")
public class WebConfig {
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

5. 请求处理

5.1 控制器方法

控制器方法通过 @RequestMapping 注解映射请求,可以指定请求方法、路径等:

@Controller
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable("id") Long id, Model model) {
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "userDetail";
    }

    @PostMapping
    public String createUser(@ModelAttribute User user) {
        userService.save(user);
        return "redirect:/user/list";
    }
}

5.2 路径变量和请求参数

使用 @PathVariable@RequestParam 获取路径变量和请求参数:

@GetMapping("/search")
public String search(@RequestParam("query") String query, Model model) {
    List<User> users = userService.search(query);
    model.addAttribute("users", users);
    return "userList";
}

5.3 数据绑定和校验

Spring MVC 提供了自动数据绑定的功能,可以通过 @ModelAttribute 和 JSR-303 注解实现数据校验:

@PostMapping
public String createUser(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "userForm";
    }
    userService.save(user);
    return "redirect:/user/list";
}

6. 视图解析

6.1 JSP 视图

使用 JSP 作为视图技术时,可以通过 JSP 文件来渲染模型数据。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    User List


User List

ID Name
${user.id} ${user.name}

6.2 Thymeleaf 视图

Thymeleaf 是一个现代的服务器端 Java 模板引擎,支持 HTML5 和模板语法。

DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>User Listtitle>
head>
<body>
<h1>User Listh1>
<table>
    <tr>
        <th>IDth>
        <th>Nameth>
    tr>
    <tr th:each="user : ${users}">
        <td th:text="${user.id}">td>
        <td th:text="${user.name}">td>
    tr>
table>
body>
html>

7. 异常处理

7.1 全局异常处理

使用 @ControllerAdvice 定义全局异常处理,处理所有控制器的异常:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(UserNotFoundException.class)
    public ModelAndView handleUserNotFound(UserNotFoundException ex) {
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("message", ex.getMessage());
        return modelAndView;
    }
}

7.2 自定义异常

可以自定义异常类,并在控制器中抛出以便统一处理。

public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

8. 拦截器

8.1 定义拦截器

拦截器实现 HandlerInterceptor 接口,可以在请求处理前、后执行逻辑。

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 处理前逻辑
        return true; // 继续请求处理
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        // 处理后逻辑
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 完成后逻辑
    }
}

8.2 注册拦截器

拦截器需要在配置类中注册。你可以通过实现 WebMvcConfigurer 接口来注册自定义的拦截器:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**") // 拦截所有请求
                .excludePathPatterns("/login"); // 排除登录请求
    }
}

9. RESTful 风格的 API

Spring MVC 也非常适合构建 RESTful 风格的 API。可以使用 @RestController 注解简化返回 JSON 数据的操作。

9.1 REST 控制器示例

@RestController
@RequestMapping("/api/users")
public class UserRestController {

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
    }

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
}

10. 数据验证

Spring MVC 支持 JSR-303 规范的注解来进行数据验证。可以在模型类中使用注解定义验证规则。

10.1 模型类示例

import javax.validation.constraints.NotBlank;

public class User {
    private Long id;

    @NotBlank(message = "Name is required")
    private String name;

    // getters and setters
}

10.2 控制器中的验证

在控制器中,结合 @Valid 注解进行数据验证:

@PostMapping
public String createUser(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "userForm"; // 返回到表单视图
    }
    userService.save(user);
    return "redirect:/user/list";
}

11. 文件上传

Spring MVC 提供了文件上传的支持,可以通过 @RequestParam 轻松处理文件上传。

11.1 文件上传控制器

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("/upload")
public class FileUploadController {

    @PostMapping
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        if (!file.isEmpty()) {
            // 处理文件保存逻辑
        }
        return "redirect:/upload/success";
    }
}

11.2 视图示例

在 JSP 或 Thymeleaf 视图中使用表单上传文件:

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">Uploadbutton>
form>

12. 总结

Spring MVC 是一个强大且灵活的框架,适用于构建各种类型的 Web 应用程序。通过 MVC 设计模式的实现,Spring MVC 提供了良好的结构化方式来分离业务逻辑和表现层。

本文概述了 Spring MVC 的核心知识点,包括工作原理、关键组件、请求处理、数据绑定、异常处理、文件上传等。掌握这些知识点将有助于你在实际开发中高效地使用 Spring MVC。希望本文能够帮助你深入理解和应用 Spring MVC 框架。

你可能感兴趣的:(spring,mvc,java)