当前位置: 首页 > article >正文

Spring MVC概述

1.1 MVC设计模式

MVC(Model-View-Controller)是一种软件设计模式,旨在将应用程序的业务逻辑、用户界面和用户输入分离。Spring MVC遵循这一模式,提供了以下几个核心组件:

  • Model:表示应用程序的数据和业务逻辑。
  • View:负责呈现模型数据的用户界面。
  • Controller:接收用户输入并调用相应的业务逻辑。
生活场景比喻
  • Model:厨房,负责准备食材和做菜。
  • View:餐桌,展示菜品和菜单。
  • Controller:服务员,负责接收你的订单,并将其传递给厨房。

1.2 Spring MVC的核心组件

  • DispatcherServlet:前端控制器,负责接收请求并将其分发到相应的处理器。
  • HandlerMapping:根据请求的URL找到对应的处理器。
  • Controller:处理请求的业务逻辑。
  • HandlerAdapter:用于调用具体的处理器。
  • ViewResolver:根据视图名称解析出具体的视图实现。
  • ModelAndView:封装模型数据和视图信息的对象。

1.3 Spring MVC的工作流程

Spring MVC的工作流程如下:

  1. 客户端发送请求到DispatcherServlet
  2. DispatcherServlet通过HandlerMapping查找对应的Controller
  3. Controller处理请求并返回ModelAndView对象。
  4. DispatcherServlet通过ViewResolver解析视图。
  5. 渲染视图并返回响应给客户端。
生活场景比喻
  1. 客户(客户端)向服务员DispatcherServlet)下单。
  2. 服务员根据订单(请求的URL)找到对应的厨师Controller)。
  3. 厨师准备好菜品(处理请求),并返回给服务员(ModelAndView)。
  4. 服务员将菜品放在餐桌上(视图),客户享用美食。

二、Spring MVC的请求处理

2.1 DispatcherServlet的实现

DispatcherServlet是Spring MVC的核心组件,负责接收和处理所有HTTP请求。它是前端控制器,所有请求首先到达这里。 (Spring Boot应用中添加@SpringBootApplication注解,框架会自动创建并配置一个DispatcherServlet

public class DispatcherServlet extends HttpServlet {
    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) {
        // 1. 获取请求的处理器
        HandlerExecutionChain handler = getHandler(request);
        // 2. 执行处理器
        ModelAndView mv = handlerAdapter.handle(request, response, handler.getHandler());
        // 3. 渲染视图
        render(mv, request, response);
    }
}

2.2 HandlerMapping的实现

HandlerMapping用于将请求映射到对应的处理器。Spring MVC提供多种实现,最常用的是RequestMappingHandlerMapping

public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
    @Override
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
        // 1. 根据请求信息找到对应的HandlerMethod
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
            if (entry.getKey().matches(request)) {
                return entry.getValue();
            }
        }
        return null;
    }
}

2.3 Controller的实现

Controller是业务逻辑的处理器,负责接收请求并返回模型和视图。

@Controller
public class MyController {
    @RequestMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Hello, World!");
        return "helloView"; // 返回视图名称
    }
}

2.4 HandlerAdapter的实现

HandlerAdapter负责调用具体的处理器方法,并返回一个ModelAndView对象。

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter {
    @Override
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 执行Controller的方法
        Method method = ((HandlerMethod) handler).getMethod();
        Object returnValue = method.invoke(handler, ...); // 传入方法参数
        return new ModelAndView("viewName", "model", returnValue);
    }
}

2.5 ViewResolver的实现

ViewResolver根据视图名称解析出实际的视图实现。

public class InternalResourceViewResolver extends AbstractUrlBasedViewResolver {
    @Override
    protected View createView(String viewName, Locale locale) throws Exception {
        // 1. 创建JSP视图
        String url = getPrefix() + viewName + getSuffix();
        return new JstlView(url);
    }
}

三、Spring MVC的请求参数处理

3.1 请求参数的获取

Spring MVC提供了多种方式来获取请求参数。可以使用@RequestParam注解来获取单个参数,也可以使用@RequestParam注解结合数组或集合来获取多个参数。

@GetMapping("/greet")
public String greet(@RequestParam String name, Model model) {
    model.addAttribute("message", "Hello, " + name);
    return "greetView";
}

3.2 请求体的处理

对于POST请求,Spring MVC可以使用@RequestBody注解将请求体中的JSON数据自动转换为Java对象。

@PostMapping("/user")
public ResponseEntity<User> createUser(@RequestBody User user) {
    // 处理用户创建逻辑
    return ResponseEntity.ok(user);
}

3.3 文件上传处理

Spring MVC支持文件上传,可以使用MultipartFile来处理上传的文件。

@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
    // 处理文件上传逻辑
    return "uploadSuccessView";
}

四、Spring MVC的视图解析

4.1 视图解析器的配置

视图解析器用于将视图名称解析为实际的视图实现。Spring MVC支持多种视图技术,如JSP、Thymeleaf、Freemarker等。

@Bean
public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    return resolver;
}

4.2 JSP视图的使用

jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <title>Hello Page</title>
</head>
<body>
    <h1>${message}</h1>
</body>
</html>

4.3 Thymeleaf视图的使用

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

html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello Page</title>
</head>
<body>
    <h1 th:text="${message}">Hello, World!</h1>
</body>
</html>

五、Spring MVC的异常处理

5.1 全局异常处理

Spring MVC提供了全局异常处理机制,可以使用@ControllerAdvice注解定义一个全局异常处理类。

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
    }
}

5.2 自定义异常处理

除了全局异常处理,还可以在Controller中使用@ExceptionHandler注解处理特定异常。

@Controller
public class MyController {
    @GetMapping("/error")
    public String error() {
        throw new RuntimeException("Something went wrong");
    }

    @ExceptionHandler(RuntimeException.class)
    public String handleRuntimeException(RuntimeException e) {
        return "errorView"; // 返回错误视图
    }
}

六、Spring MVC的拦截器

6.1 拦截器的定义

拦截器可以在请求处理之前和之后执行一些操作。可以通过实现HandlerInterceptor接口定义一个拦截器。

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行
        return true; // 返回true继续执行,返回false则中断请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求处理之后执行
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在请求完成之后执行
    }
}

6.2 拦截器的注册

可以通过实现WebMvcConfigurer接口将拦截器注册到Spring MVC中。

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦截所有请求
    }
}

七、Spring MVC的安全性

7.1 Spring Security的集成

Spring Security是一个强大的安全框架,可以与Spring MVC无缝集成。以下是基本的集成步骤:

  1. 添加Spring Security依赖。
  2. 创建Security配置类,继承WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/public/**").permitAll() // 公开路径
            .anyRequest().authenticated() // 其他路径需要认证
            .and()
            .formLogin(); // 表单登录
    }
}

7.2 基于注解的安全控制

可以使用@PreAuthorize@PostAuthorize注解进行方法级别的安全控制。  

八、Spring MVC的测试

8.1 单元测试

可以使用JUnit和Spring Test进行Spring MVC的单元测试。

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGreet() throws Exception {
        mockMvc.perform(get("/greet").param("name", "John"))
            .andExpect(status().isOk())
            .andExpect(model().attribute("message", "Hello, John"));
    }
}

8.2 集成测试

使用@SpringBootTest进行集成测试。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testGreet() {
        ResponseEntity<String> response = restTemplate.getForEntity("/greet?name=John", String.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
    }
}

九、Spring MVC的处理流程

9.1 详细处理流程

Spring MVC的处理流程主要分为以下几个步骤:

  1. 请求到达DispatcherServlet:客户端发送HTTP请求,首先到达DispatcherServlet,它是所有请求的入口。
  2. 查找处理器DispatcherServlet使用HandlerMapping查找对应的处理器(Controller)。它根据请求的URL和HTTP方法来匹配合适的处理器。
  3. 执行处理器:找到处理器后,DispatcherServlet使用HandlerAdapter执行该处理器。处理器方法被调用,并处理请求。
  4. 返回ModelAndView:处理器方法返回一个ModelAndView对象,包含模型数据和视图信息。
  5. 视图解析DispatcherServlet使用ViewResolver解析视图名称,找到实际的视图实现(如JSP、Thymeleaf等)。
  6. 渲染视图:视图被渲染,并将最终的HTML响应返回给客户端。
生活场景比喻
  1. 客户(客户端)向服务员DispatcherServlet)下单。
  2. 服务员根据订单(请求的URL)找到对应的厨师Controller)。
  3. 厨师准备好菜品(处理请求),并返回给服务员(ModelAndView)。
  4. 服务员将菜品放在餐桌上(视图),客户享用美食。

十、Spring MVC如何统一封装响应信息?

1. ApiResponse类定义

我们定义一个通用的ApiResponse类,可以接收任意类型的数据。

public class ApiResponse<T> {
    private int status; // 响应状态码
    private String message; // 响应消息
    private T data; // 响应数据

    // 构造函数
    public ApiResponse(int status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    // Getter和Setter方法
    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
2. GlobalResponseWrapper类

GlobalResponseWrapper中,可以使用不同的方法来处理不同类型的响应。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;

@ControllerAdvice // 该注解用于定义全局的异常处理和响应封装
public class GlobalResponseWrapper {

    // 处理所有未处理的异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<Object>> handleException(Exception e) {
        // 创建一个统一的响应对象,状态码为500,包含异常信息
        ApiResponse<Object> response = new ApiResponse<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), null);
        // 返回响应实体,包含HTTP状态和响应体
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }

    // 在每个请求中添加统一的成功响应结构
    @ModelAttribute
    public void wrapResponse(Model model) {
        // 向模型中添加一个成功的响应对象
        model.addAttribute("apiResponse", new ApiResponse<>(200, "Success", null));
    }
}
3. 控制器示例

在控制器中,可以根据不同的情况返回字符串或对象。

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

@RestController
public class SampleController {

    // 返回字符串响应
    @GetMapping("/message")
    public ResponseEntity<ApiResponse<String>> getMessage() {
        // 创建一个字符串响应
        ApiResponse<String> response = new ApiResponse<>(200, "Success", "Hello, this is a string response!");
        return ResponseEntity.ok(response);
    }

    // 返回对象响应
    @GetMapping("/user")
    public ResponseEntity<ApiResponse<User>> getUser() {
        // 创建一个用户对象
        User user = new User(1, "John Doe", "john@example.com");
        // 创建一个对象响应
        ApiResponse<User> response = new ApiResponse<>(200, "Success", user);
        return ResponseEntity.ok(response);
    }
}
4. 用户类定义

定义一个简单的用户类User,以便在响应中使用。

public class User {
    private int id; // 用户ID
    private String name; // 用户姓名
    private String email; // 用户邮箱

    // 构造函数
    public User(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // Getter和Setter方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

生活场景比喻

  • 状态码(status):就像菜单卡上的价格,告诉你这道菜的价值。
  • 消息(message):就像菜单卡上的描述,告诉你这道菜的特点和风味。
  • 数据(data):就像你点的菜品本身,是你真正想要的内容。

 设计模式

  • 模板方法模式:在GlobalResponseWrapper中,使用了模板方法模式,通过定义统一的异常处理和成功响应的封装,确保所有控制器都遵循相同的响应结构。这种方式使得代码更加一致。

  • 建造者模式:虽然在这个示例中没有明显使用建造者模式,但可以看到ApiResponse类的构造函数允许灵活创建响应对象。将复杂的对象构建过程封装在构造函数中,提升了代码的可读性。

十一、Spring MVC如何处理Date相关的参数

11.1 日期参数处理

在Web应用中,处理日期参数是一项常见需求。Spring MVC提供了多种方式来处理日期参数,例如使用@DateTimeFormat注解。

11.2 使用@DateTimeFormat

可以在控制器的方法参数上使用@DateTimeFormat注解来指定日期格式。

@GetMapping("/date")
public String getDate(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
    // 处理日期逻辑
    return "dateView";
}

11.3 自定义日期格式化器

如果需要更复杂的日期处理,可以自定义格式化器。

@Component
public class CustomDateFormatter implements Formatter<LocalDate> {
    @Override
    public LocalDate parse(String text, Locale locale) throws ParseException {
        return LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    @Override
    public String print(LocalDate object, Locale locale) {
        return object.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }
}

十二、相关问题

12.1 常见问题

1. Spring MVC的核心组件

1.1 DispatcherServlet
  • 作用:DispatcherServlet是Spring MVC的前端控制器,负责接收所有HTTP请求并将其分发到相应的处理器(Controller)。它是整个Spring MVC框架的核心。
1.2 HandlerMapping
  • 作用:HandlerMapping用于根据请求的URL查找匹配的Controller。它将请求映射到具体的处理方法,并为DispatcherServlet提供相应的处理器信息。
1.3 Controller
  • 作用:Controller是处理请求的核心组件。它接收来自DispatcherServlet的请求,执行业务逻辑,并返回一个ModelAndView对象,封装了模型数据和视图信息。
1.4 HandlerAdapter
  • 作用:HandlerAdapter用于调用具体的处理方法。它支持多种类型的处理器(Controller),并且以统一的方式调用这些处理器的方法。
1.5 ViewResolver
  • 作用:ViewResolver用于解析视图名称,将其转换为实际的视图实现。它根据返回的视图名称找到对应的视图(如JSP、Thymeleaf等),并将模型数据传递给视图进行渲染。

2. Spring MVC的请求处理流程

  1. 客户端发送请求:用户通过浏览器发送HTTP请求,目标URL对应于DispatcherServlet。
  2. DispatcherServlet接收请求:DispatcherServlet作为前端控制器,接收所有请求。
  3. HandlerMapping查找Controller:DispatcherServlet通过HandlerMapping查找与请求URL匹配的Controller。
  4. Controller处理请求:找到相应的Controller后,DispatcherServlet调用该Controller的方法处理请求,并返回一个ModelAndView对象。
  5. HandlerAdapter调用处理方法:HandlerAdapter负责调用具体的处理方法,确保请求的处理逻辑被执行。
  6. ViewResolver解析视图:DispatcherServlet使用ViewResolver解析返回的视图名称,找到实际的视图实现。
  7. 渲染视图并返回响应:视图被渲染后,生成的HTML内容被返回给客户端,完成请求处理。

3. 如何在Spring MVC中处理异常?

3.1 全局异常处理的实现方式

使用@ControllerAdvice@ExceptionHandler注解可以实现全局异常处理,捕获应用中的所有未处理异常,并返回统一的错误响应。

3.2 示例代码
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice // 定义全局异常处理
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) // 捕获所有异常
    public ResponseEntity<ApiResponse<String>> handleException(Exception e) {
        // 创建统一的错误响应
        ApiResponse<String> response = new ApiResponse<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), null);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
}

4. Spring MVC与Spring Boot的区别是什么?

  • Spring MVC是一个用于构建Web应用程序的框架,而Spring Boot是一个用于快速构建Spring应用程序的工具,简化了Spring配置。
  • Spring Boot提供了自动配置功能,简化了Spring MVC的配置过程,允许开发者快速启动项目。
  • Spring Boot集成了Spring MVC,可以通过简单的注解和配置快速构建RESTful API。

5. 如何处理Spring MVC中的跨域请求(CORS)?

  • 可以在Spring MVC中通过@CrossOrigin注解来处理跨域请求。
  • 也可以在WebMvcConfigurer接口的实现中重写addCorsMappings方法进行全局配置。
示例代码:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 允许所有路径
                .allowedOrigins("http://example.com") // 允许的来源
                .allowedMethods("GET", "POST", "PUT", "DELETE"); // 允许的方法
    }
}

6 Spring MVC如何支持文件上传?

  • 可以使用MultipartFile类来处理文件上传。
  • 需要在配置文件中设置文件上传的大小限制和其他相关配置。
示例代码:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {
        // 处理文件上传
        if (!file.isEmpty()) {
            // 保存文件或其他操作
            return "File uploaded successfully: " + file.getOriginalFilename();
        }
        return "File upload failed.";
    }
}

7. Spring MVC如何实现请求参数的验证?

  • 可以使用JSR-303/JSR-380(如Hibernate Validator)进行请求参数的验证。
  • 在模型类属性上使用注解,如@NotNull@Size等,结合@Valid注解进行验证。
示例代码:
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotNull(message = "Name cannot be null")
    @Size(min = 2, max = 30, message = "Name must be between 2 and 30 characters")
    private String name;

    // getters and setters
}

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/user")
    public String createUser(@Valid @RequestBody User user) {
        return "User created: " + user.getName();
    }
}

8. Spring MVC如何实现请求的限流?

  • 可以使用AOP(面向切面编程)来实现请求限流,记录请求次数并限制频率。
  • 还可以使用第三方库,如Bucket4j或Guava RateLimiter,来实现更复杂的限流策略。
示例代码:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class RateLimiterAspect {

    private final RateLimiter rateLimiter = RateLimiter.create(1.0); // 每秒1个请求

    @Before("execution(* com.example.controller.*.*(..))")
    public void limit() {
        if (!rateLimiter.tryAcquire()) {
            throw new RuntimeException("Too many requests");
        }
    }
}

9. Spring MVC如何支持异步请求

  • 可以使用@Async注解将方法标记为异步执行。
  • 还可以使用DeferredResultCallable来处理异步请求,避免阻塞。
示例代码:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

@RestController
public class AsyncController {

    @GetMapping("/async")
    public DeferredResult<String> async() {
        DeferredResult<String> deferredResult = new DeferredResult<>();
        // 模拟异步处理
        new Thread(() -> {
            try {
                Thread.sleep(2000); // 模拟耗时操作
                deferredResult.setResult("Async response");
            } catch (InterruptedException e) {
                deferredResult.setErrorResult("Error occurred");
            }
        }).start();
        return deferredResult;
    }
}

10. Spring MVC中的拦截器(Interceptor)是什么?如何使用?

  • 拦截器用于在请求处理前后进行处理,可以用于日志记录、权限验证等。
  • 需要实现HandlerInterceptor接口并在配置类中注册拦截器。
示例代码:
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 请求处理前逻辑
        System.out.println("Request intercepted: " + request.getRequestURI());
        return true; // 返回true继续处理,false则停止
    }
}

import org.springframework.beans.factory.annotation.Autowired;
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 {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**"); // 拦截所有请求
    }
}

 


http://www.kler.cn/a/282792.html

相关文章:

  • FreeRTOS的列表与列表项
  • 【卡尔曼滤波】数据融合Fusion的应用 C语言、Python实现(Kalman Filter)
  • 【Window主机访问Ubuntu从机——Xrdp配置与使用】
  • uni-app表格带分页,后端处理过每页显示多少条
  • 论文 | The Capacity for Moral Self-Correction in LargeLanguage Models
  • 使用Element UI实现前端分页,及el-table表格跨页选择数据,切换分页保留分页数据,限制多选数量
  • (三)Kafka离线安装 - ZooKeeper开机自启
  • 搭建自己的金融数据源和量化分析平台(八):解析PDF财报中的资产负债表
  • Power BI仪表盘与报告实施方案:让数据变得生动且有用!
  • 目标检测:Cascade R-CNN: Delving into High Quality Object Detection - 2017【方法解读】
  • 【解析几何笔记】12.向量的混合积及其应用
  • 51单片机——数码管控制
  • STM32(F103ZET6)第二十课:FreeRtos操作系统的应用
  • 低代码归根结底差不多,但又差很多
  • WPF框架(Prism 和 Community Toolkit)区别点
  • Docker原理及实例
  • WPF UserControl 进行界面绑定,怎么进行内存释放
  • linux中下载nginx
  • 闲鱼ip属地怎么查看?闲鱼怎么修改ip属地
  • 高级前端工程师React面试题
  • Esxi学习记录
  • 天工股份业绩暴增之谜,与第一大客户常州索罗曼的神秘关联疑点
  • 【YOLOv8改进[Conv]】 感受野注意力卷积RFAConv(2024.3)| 使用RFAConv改进目标检测效果 + 含全部代码和详细修改方式
  • 双系统安装:一键解锁电脑新境界,Windows与Linux并肩作战!
  • 0基础学习Python路径(27)sys模块
  • 深入探究Nginx中的URL哈希负载均衡策略