SpringMVC核心、两种视图解析方法、过滤器拦截器 “ / “ 的意义

发布于:2025-02-11 ⋅ 阅读:(29) ⋅ 点赞:(0)

SpringMVC的执行流程

1. Spring MVC 的视图解析机制

Spring MVC 的核心职责之一是将数据绑定到视图并呈现给用户。它通过 视图解析器(View Resolver) 来将逻辑视图名称解析为具体的视图文件(如 HTML、JSP)。

核心流程

  1. Controller 处理请求

    • Controller 方法可以通过返回 逻辑视图名称ModelAndView 对象来决定视图和数据。
  2. 视图解析器解析视图名称

    • 视图名称由 ViewResolver 解析为实际视图文件路径。
  3. 模型数据绑定到视图

    • 数据由 ModelModelAndView 提供,Spring MVC 会将数据传递给视图引擎渲染。

常见视图解析器

  1. Thymeleaf 视图解析器

    • Spring Boot 默认集成了 Thymeleaf,只需配置模板路径:

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

  1. JSP 视图解析器

    • 通过 InternalResourceViewResolver  或者xml配置文件配置:
    • @Bean
      public InternalResourceViewResolver jspViewResolver() {
          InternalResourceViewResolver resolver = new InternalResourceViewResolver();
          resolver.setPrefix("/WEB-INF/views/");
          resolver.setSuffix(".jsp");
          return resolver;
      }
      


2. ModelModelAndView 的作用与区别

2.1 Model 的作用

  • 职责:仅负责传递数据。
  • 特点
    • Model 是一个数据容器。
    • 不能直接设置视图名称。
    • Spring 自动将 Model 中的数据绑定到视图。
  • 常用场景
    • 数据简单,视图名称固定,返回视图逻辑名称。
@RequestMapping("/exampleModel")
public String example(Model model) {
    model.addAttribute("message", "Hello from Model");
    return "viewName"; // 返回逻辑视图名称
}

2.2 ModelAndView 的作用

  • 职责:同时封装视图名称和数据。
  • 特点
    • 既可以设置视图名称,也可以传递数据。
    • 可以动态调整视图名称和数据,灵活性更高。
  • 常用场景
    • 视图名称需要动态确定,或者需要同时设置多个数据。
@RequestMapping("/exampleModelAndView")
public ModelAndView exampleModelAndView() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("viewName"); // 设置视图名称
    mav.addObject("message", "Hello from ModelAndView");
    return mav;
}

2.3 ModelModelAndView 的对比

特性 Model ModelAndView
职责 传递数据 传递数据并设置视图名称
视图名称设置 通过返回值设置 通过 setViewName 设置
灵活性 较低 较高
适用场景 固定视图名称,数据传递较简单的场景 动态视图名称或需要同时传递多个数据的场景

3. ModelModelAndView 配合视图解析的用法

以下分别说明 ThymeleafJSP 的用法。


3.1 配合 Thymeleaf

(1)使用 Model

通过 Model 传递数据,并返回视图的逻辑名称。

@RequestMapping("/thymeleaf/model")
public String useModel(Model model) {
    model.addAttribute("message", "Hello from Model");
    model.addAttribute("title", "Thymeleaf Example");
    return "example"; // 解析为 /templates/example.html
}

对应 Thymeleaf 模板文件 (example.html):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:text="${title}">Default Title</title>
</head>
<body>
    <h1 th:text="${message}">Default Message</h1>
</body>
</html>

(2)使用 ModelAndView

通过 ModelAndView 同时设置视图名称和数据。

@RequestMapping("/thymeleaf/modelAndView")
public ModelAndView useModelAndView() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("example"); // 解析为 /templates/example.html
    mav.addObject("message", "Hello from ModelAndView");
    mav.addObject("title", "Thymeleaf Example with ModelAndView");
    return mav;
}

3.2 配合 JSP

(1)使用 Model

通过 Model 传递数据,并返回视图的逻辑名称。

@RequestMapping("/jsp/model")
public String useModel(Model model) {
    model.addAttribute("message", "Hello from Model");
    model.addAttribute("title", "JSP Example");
    return "example"; // 解析为 /WEB-INF/views/example.jsp
}

对应 JSP 文件 (example.jsp):

<!DOCTYPE html>
<html>
<head>
    <title>${title}</title>
</head>
<body>
    <h1>${message}</h1>
</body>
</html>

(2)使用 ModelAndView

通过 ModelAndView 同时设置视图名称和数据。

@RequestMapping("/jsp/modelAndView")
public ModelAndView useModelAndView() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("example"); // 解析为 /WEB-INF/views/example.jsp
    mav.addObject("message", "Hello from ModelAndView");
    mav.addObject("title", "JSP Example with ModelAndView");
    return mav;
}

3.3 总结

特性 Thymeleaf JSP
视图路径配置 classpath:/templates/ /WEB-INF/views/
支持数据传递 支持 ModelModelAndView 支持 ModelModelAndView
模板引擎风格 现代化 HTML5 传统 Java 模板
性能 高效 较低

4. 综合总结

4.1 ModelModelAndView 的选择

  1. 简单场景:使用 Model 配合返回视图逻辑名称。
  2. 复杂场景:使用 ModelAndView 同时设置视图名称和数据。

4.2 配合视图解析器

  • ThymeleafJSP 均支持 ModelModelAndView,用法完全一致。
  • 如果是新项目,推荐使用 Thymeleaf。

4.3 推荐实践

  • 优先使用 Model 和逻辑视图名称返回方式,更简洁清晰。
  • 在需要动态调整视图名称或复杂数据传递时,使用 ModelAndView

过滤器、拦截器、路径匹配规则与应用

以下是关于 过滤器(Filter)拦截器(Interceptor) 的核心内容,以及路径匹配中 //*/** 的使用规则和场景总结。


1. 过滤器(Filter)

1.1 定义

  • 属于 Servlet 规范的一部分,运行在 Servlet 容器中。
  • 用于对所有 HTTP 请求和响应进行预处理和后处理。

1.2 特点

  • 作用范围广:可以作用于动态资源(如 API 请求)和静态资源(如 HTML、CSS、JS)。
  • 生命周期:由 Servlet 容器管理,启动时初始化过滤器,容器销毁时释放过滤器。
  • 使用场景:适用于跨域处理、编码设置、访问日志记录、请求参数过滤等基础功能。

1.3 示例

  • 典型实现
    @WebFilter("/*")
    public class MyFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("Filter: Before processing request");
            chain.doFilter(request, response); // 执行后续逻辑
            System.out.println("Filter: After processing request");
        }
    }
    


2. 拦截器(Interceptor)

2.1 定义

  • 属于 Spring 框架的一部分,运行在 Spring MVC 的 DispatcherServlet 内部。
  • 用于拦截由 Spring 处理的动态资源(如控制器方法)。

2.2 特点

  • 作用范围窄:仅作用于 Spring MVC 控制的请求(动态资源)。
  • 生命周期:由 Spring 容器管理,在 Spring 启动时加载,关闭时销毁。
  • 使用场景:适用于业务权限校验、登录校验、动态数据封装等业务逻辑。

2.3 示例

  • 典型实现

    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("Interceptor: Before handling request");
            return true; // 返回 false 会中断请求
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
                throws Exception {
            System.out.println("Interceptor: After handling request");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("Interceptor: After rendering view");
        }
    }
    

  • 拦截器注册

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MyInterceptor())
                    .addPathPatterns("/api/**") // 拦截所有 /api 的请求
                    .excludePathPatterns("/static/**"); // 排除静态资源
        }
    }
    


3. 过滤器与拦截器的区别

特性 过滤器(Filter) 拦截器(Interceptor)
作用范围 全局,包含静态资源和动态资源 仅作用于 Spring MVC 处理的动态资源
触发时机 DispatcherServlet 之前运行 DispatcherServlet 内部运行
适用场景 跨域、编码设置、日志记录、IP 限制等基础功能 登录校验、权限校验、业务逻辑处理等
生命周期管理 由 Servlet 容器管理 由 Spring 容器管理
实现方式 实现 Filter 接口 实现 HandlerInterceptor 接口
路径匹配能力 通过 /* 等规则匹配所有请求路径 支持 /**,匹配所有路径,包括多级子路径
静态资源支持 支持静态资源(如 HTML、CSS、JS) 不支持静态资源,只作用于动态请求

4. 路径匹配规则与应用

4.1 匹配规则

规则 匹配范围 适用场景
/ 仅匹配根路径 / 网站首页、主路径请求
/* 匹配当前路径下的一级子路径 静态资源过滤、一级子路径匹配
/** 匹配当前路径及其所有层级子路径 拦截器配置、递归匹配所有子路径

5. 综合推荐

  1. 过滤器(Filter)

    • 如果需要对所有请求(包括静态资源)进行操作,使用 /*
    • 常见场景:日志记录、编码设置、跨域处理。
  2. 拦截器(Interceptor)

    • 如果需要对动态请求(如 API 请求)进行操作,使用 /**
    • 常见场景:登录校验、权限控制、封装业务逻辑。
  3. 路径匹配规则

    • /:适用于根路径请求。
    • /*:适用于当前路径的一级子路径。
    • /**:适用于所有子路径的递归匹配。

网站公告

今日签到

点亮在社区的每一天
去签到