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

<servlet-class>和</url-pattern>的作用

在 SpringMVC 的 web.xml 配置中,<servlet-class> 和 <url-pattern> 是两个关键配置项,分别用于指定处理请求的 Servlet 类和定义该 Servlet 拦截的请求路径规则。以下是它们的具体作用及原理分析:

一、<servlet-class> 的作用

1. 指定核心前端控制器

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  • 核心作用:明确声明当前 Servlet 的实现类为 SpringMVC 的前端控制器 DispatcherServlet
    DispatcherServlet 是 SpringMVC 的入口,负责协调处理所有 Web 请求,包括请求分发、视图解析、异常处理等核心流程。
  • 本质DispatcherServlet 是 HttpServlet 的子类,遵循 Servlet 规范,通过重写 doGet/doPost 等方法实现对 SpringMVC 流程的控制。

2. 集成 SpringMVC 生态

  • 该类会自动加载 SpringMVC 的配置(如 springmvc-servlet.xml),初始化处理器映射(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)等组件,形成完整的请求处理链条。

二、<url-pattern> 的作用

1. 定义请求拦截规则

<url-pattern>/</url-pattern>
  • 核心作用:指定哪些请求会被 DispatcherServlet 处理。
    常见取值有 /*/*.do 等,不同取值影响请求的拦截范围。

2. 不同取值的区别

取值拦截范围适用场景
/*拦截 所有请求(包括静态资源 .html/.js/.css、JSP 页面请求等)。不推荐:会导致 JSP 页面无法正常访问(因 JSP 本质是 Servlet,需由 Tomcat 内置 Servlet 处理)。
/拦截 除 .jsp 以外的所有请求(静态资源、RESTful 接口等)。推荐配置:JSP 页面由 Tomcat 默认 Servlet 处理,避免与 DispatcherServlet 冲突。
*.do拦截 以 .do 结尾的请求(如 /user.do)。传统 MVC 风格,通过后缀区分动态请求,目前逐渐被 RESTful 无后缀风格取代。

3. 为什么推荐使用 <url-pattern>/</url-pattern>

  • 避免 JSP 拦截问题
    当请求为 JSP 页面(如 /index.jsp)时,Tomcat 会使用内置的 JspServlet 处理。若使用 /*DispatcherServlet 会优先拦截 JSP 请求,导致 404 错误。
    使用 / 时,DispatcherServlet 仅拦截 非 JSP 请求(JSP 的扩展名 .jsp 会被 Tomcat 直接处理),确保静态页面和动态接口的正常分发。
  • 支持 RESTful 风格
    无后缀的 URL(如 /user/1)更简洁,符合现代 Web 开发规范,且无需额外配置后缀映射。

三、请求处理流程与配置的关系

  1. 请求到达 Tomcat
    浏览器发送请求(如 /user/list 或 /index.jsp)。
  2. Tomcat 匹配 Servlet
    • 若请求是 JSP(.jsp 结尾):由 Tomcat 内置的 JspServlet 处理,直接返回页面。
    • 若请求是其他路径(如 /user/list):根据 <url-pattern>/</url-pattern>,由 DispatcherServlet 接管。
  3. DispatcherServlet 处理流程
    • 通过处理器映射(HandlerMapping)找到对应的控制器(@Controller 方法)。
    • 调用控制器处理请求,返回模型数据和视图名。
    • 视图解析器(ViewResolver)解析视图,生成最终响应(如 HTML 页面或 JSON 数据)。

四、最佳实践

配置 <url-pattern>/</url-pattern>
这是 SpringMVC 推荐的现代配置方式,兼容 RESTful 接口和静态资源,同时避免与 JSP 冲突(若项目使用 JSP 作为视图)。

静态资源处理
若项目包含静态资源(如 CSS/JS/ 图片),需在 SpringMVC 配置中额外声明静态资源映射,避免被 DispatcherServlet 拦截:

// WebMvcConfigurer 配置
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}

无 JSP 项目(如前后端分离)
若项目完全使用 JSON 响应(无 JSP 视图),可安全使用 /*,但需确保静态资源路径正确映射。

总结

  • <servlet-class>:指定 SpringMVC 的核心前端控制器 DispatcherServlet,启动请求处理的整个流程。
  • <url-pattern>/</url-pattern>:精准拦截非 JSP 请求,确保动态接口由 SpringMVC 处理,静态资源和 JSP 由 Tomcat 内置机制处理,是现代 Web 开发的最佳实践配置。
    通过合理配置这两个项,可实现请求的高效分发,避免资源访问冲突,提升项目的可维护性。



请求处理流程更加详细点



以下是 SpringMVC 请求处理流程 的详细解析,从客户端发送请求到服务器返回响应的完整链路,结合核心组件的协作机制展开说明:

一、请求处理的核心流程(12 个关键步骤)

1. 浏览器发送请求到 Tomcat

  • 用户在浏览器输入 URL(如 http://localhost:8080/app/user/list),请求通过网络到达 Tomcat 服务器。
  • Tomcat 根据 web.xml 中的 <url-pattern> 匹配处理该请求的 Servlet:
    • 若请求是 JSP 页面(如 .jsp 结尾):由 Tomcat 内置的 JspServlet 处理(直接跳过 SpringMVC)。
    • 若请求是 非 JSP 请求(如 /user/list):根据配置 url-pattern>/</url-pattern>,由 DispatcherServlet 接管。

2. DispatcherServlet 接收请求并初始化上下文

  • DispatcherServlet 作为前端控制器,是请求处理的入口,负责协调所有后续组件。
  • 它会加载 SpringMVC 配置文件(如 springmvc-servlet.xml 或通过 Java 配置类),初始化以下核心组件(在第一次请求时完成初始化):
    • 处理器映射器(HandlerMapping):将请求 URL 映射到具体的控制器(@Controller 方法)。
    • 处理器适配器(HandlerAdapter):适配不同类型的控制器(如 @RequestMapping 方法、HttpRequestHandler 等)。
    • 视图解析器(ViewResolver):将逻辑视图名解析为具体的视图对象(如 JSP、Thymeleaf 模板、JSON 视图等)。
    • 其他组件:如异常处理器(HandlerExceptionResolver)、文件上传解析器(MultipartResolver)等。

3. 处理器映射器(HandlerMapping)查找 Handler

  • 目标:根据请求 URL 找到对应的 处理器(Handler),即处理该请求的控制器方法。
  • 工作机制
    • 遍历所有已注册的 HandlerMapping(如 RequestMappingHandlerMapping),尝试匹配请求 URL。
    • 例如,对于 URL /user/list,若存在 @RequestMapping("/user/list") 注解的方法,则返回一个 HandlerExecutionChain 对象,包含:
      • Handler:具体的控制器方法(如 UserController.list())。
      • 拦截器链(Interceptor List):请求处理前后执行的拦截器(如 HandlerInterceptor 的 preHandle/postHandle 方法)。
  • 输出:返回 HandlerExecutionChain,若未找到匹配的 Handler,则抛出 404 Not Found 异常。

4. 处理器适配器(HandlerAdapter)调用 Handler

  • 目标:适配不同类型的 Handler,确保统一调用方式。
  • 工作机制
    • DispatcherServlet 根据 Handler 的类型选择对应的 HandlerAdapter(如 RequestMappingHandlerAdapter 处理 @Controller 方法)。
    • 调用 HandlerAdapter.handle() 方法,执行以下操作:
      1. 预处理:解析请求参数(如 @RequestParam@RequestBody),绑定到控制器方法的参数列表。
      2. 调用控制器:执行具体的控制器方法,返回 ModelAndView(或 voidStringResponseEntity 等类型,由适配器转换为 ModelAndView)。
      • ModelAndView 包含:
        • Model:视图渲染所需的数据(如 Map<String, Object>)。
        • ViewName:逻辑视图名(如 user/list)或直接是 View 对象(如 InternalResourceView 对应 JSP)。

5. 拦截器前置处理(preHandle)

  • 在调用控制器方法 之前,拦截器链中的所有拦截器依次执行 preHandle() 方法:
    • 可用于权限校验、日志记录、请求参数修改等。
    • 若某拦截器返回 false,则中断后续流程,直接执行 afterCompletion()(不会调用控制器和后续拦截器)。

6. 执行控制器(@Controller 方法)

  • 控制器方法被调用,处理业务逻辑:
    • 接收请求参数(通过 @RequestParam@PathVariable 等注解)。
    • 调用服务层、持久层获取数据。
    • 返回结果:
      • 若返回 String:表示逻辑视图名(如 success),结合视图解析器生成最终视图。
      • 若返回 ModelAndView:直接包含视图名和模型数据。
      • 若返回 void:需通过 HttpServletResponse 直接输出响应(如 RESTful 接口返回 JSON 时,需配合 @ResponseBody 注解)。

7. 拦截器后置处理(postHandle)

  • 在控制器方法 执行之后、视图渲染之前,拦截器链逆序执行 postHandle() 方法:
    • 可用于修改模型数据(ModelAndView 中的 Model)、补充响应头信息等。

8. 视图解析器(ViewResolver)解析视图

  • 目标:将逻辑视图名(如 user/list)转换为具体的 View 对象。
  • 工作机制
    • 遍历所有已注册的 ViewResolver(如 InternalResourceViewResolver 处理 JSP)。
    • 例如,配置 prefix="/WEB-INF/views/" 和 suffix=".jsp",则视图名 user/list 会被解析为:

      java

      View = new InternalResourceView("/WEB-INF/views/user/list.jsp");
      
  • 支持的视图类型:JSP、Thymeleaf、Freemarker、JSON(如 MappingJackson2JsonView)、XML 等。

9. 视图渲染(View.render ())

  • 目标:将模型数据填充到视图中,生成最终的响应内容(如 HTML、JSON、XML 等)。
  • 工作机制
    • View 对象调用 render(Model, request, response) 方法:
      • 对于 JSP 视图:将 Model 数据放入 request 或 session 作用域,转发到 JSP 页面,JSP 通过 EL 表达式或标签库获取数据并渲染。
      • 对于 JSON 视图(配合 @ResponseBody):直接将模型数据序列化为 JSON 格式,写入 HttpServletResponse 的输出流。
  • 注意:若控制器方法返回 @ResponseBody 或 ResponseEntity,则跳过视图解析器,直接由 HttpMessageConverter(如 MappingJackson2HttpMessageConverter)处理响应数据。

10. 拦截器完成处理(afterCompletion)

  • 在视图渲染 完成后,拦截器链逆序执行 afterCompletion() 方法:
    • 用于资源清理(如关闭数据库连接、记录耗时日志等),无论请求是否成功都会执行。

11. DispatcherServlet 返回响应

  • 生成的响应内容(如 HTML 页面、JSON 数据)通过 HttpServletResponse 发送回浏览器。

12. 浏览器解析响应并展示

  • 浏览器接收响应,解析 HTML/JSON 等内容,渲染页面或处理数据(如 AJAX 请求的回调函数)。

二、核心组件的协作关系图

浏览器请求 → Tomcat → DispatcherServlet↓[1] 处理器映射器(HandlerMapping) ↓   (返回 HandlerExecutionChain:Handler + 拦截器链)[2] 处理器适配器(HandlerAdapter) ↓   (调用 Controller 方法,返回 ModelAndView)[3] 视图解析器(ViewResolver)   ↓   (解析为 View 对象)[4] 视图渲染(View.render())     ↓响应返回浏览器

三、关键组件的作用与扩展点

1. 处理器映射器(HandlerMapping)

  • 默认实现
    • RequestMappingHandlerMapping:处理 @RequestMapping 注解的控制器。
    • BeanNameUrlHandlerMapping:按 Bean 名称映射 URL(较少使用)。
  • 扩展:自定义 HandlerMapping,实现特殊的 URL 匹配逻辑(如基于数据库的动态路由)。

2. 处理器适配器(HandlerAdapter)

  • 默认实现
    • RequestMappingHandlerAdapter:支持 @Controller 注解的方法(最常用)。
    • SimpleControllerHandlerAdapter:支持实现 Controller 接口的控制器(传统方式)。
  • 扩展:自定义 HandlerAdapter,支持非标准的控制器类型(如自定义函数式处理器)。

3. 视图解析器(ViewResolver)

  • 默认实现
    • InternalResourceViewResolver:解析 JSP 视图(转发到 WEB-INF 目录下的页面)。
    • ThymeleafViewResolver:解析 Thymeleaf 模板(需集成 Thymeleaf 依赖)。
  • 扩展:自定义 ViewResolver,支持自定义视图类型(如 Markdown 视图、Excel 导出视图)。

4. 拦截器(Interceptor)

  • 作用:在请求处理的 前、中、后 阶段插入自定义逻辑,实现:
    • 登录校验(preHandle)。
    • 性能监控(记录方法执行时间)。
    • 响应数据包装(统一添加响应头)。
  • 实现:自定义类实现 HandlerInterceptor 接口,重写 preHandle/postHandle/afterCompletion 方法,并通过 WebMvcConfigurer.addInterceptors() 注册。

四、典型场景处理细节

1. RESTful 接口返回 JSON(无视图渲染)

  • 控制器方法添加 @ResponseBody 注解(或使用 @RestController 组合注解):

    java

    @GetMapping("/api/user/{id}")
    @ResponseBody
    public User getUser(@PathVariable Long id) {return userService.getUser(id); // 直接返回 Java 对象
    }
    
  • 流程变化:
    • 跳过视图解析器和视图渲染阶段。
    • 由 HttpMessageConverter(如 MappingJackson2HttpMessageConverter)将 Java 对象序列化为 JSON,写入响应体。

2. 文件上传处理

  • 配置 MultipartResolver(如 CommonsMultipartResolver):

    xml

    <!-- web.xml 或 Java 配置 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="10485760" /> <!-- 10MB -->
    </bean>
    
  • 控制器方法接收 MultipartFile 参数:

    java

    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {// 处理文件上传逻辑return "uploadSuccess";
    }
    
  • 流程变化:在 DispatcherServlet 处理请求前,MultipartResolver 会将 HttpServletRequest 包装为 MultipartHttpServletRequest,解析文件数据。

3. 异常处理

  • 配置 HandlerExceptionResolver(如 SimpleMappingExceptionResolver 或 @ControllerAdvice):
    • 全局捕获控制器抛出的异常,返回自定义错误页面或 JSON 响应。
  • 流程变化:若控制器方法抛出异常,会跳过视图渲染,直接由异常处理器处理,返回对应的错误视图或响应。

五、总结:SpringMVC 设计的核心思想

  1. 模块化设计:通过 DispatcherServlet 统一调度,各组件(映射器、适配器、解析器)分工明确,可独立扩展。
  2. 约定大于配置:默认组件支持大多数场景,仅需少量配置即可快速启动(如自动装配 RequestMappingHandlerMapping)。
  3. 兼容性:支持多种控制器风格(注解式、接口式)和视图技术(JSP、模板引擎、REST 响应),适配不同项目需求。

理解这一流程后,开发者可更高效地调试问题(如 404 错误可能是 Handler 未匹配,500 错误可能是视图解析失败),并利用扩展点实现个性化需求(如自定义拦截器、视图解析器)。

http://www.xdnf.cn/news/3667.html

相关文章:

  • Oracle VirtualBox 在 Windows 上的详细安装步骤
  • AnimateCC教学:照片旋转飞舞并爆炸....
  • NV189NV195美光固态闪存NV197NV199
  • 什么是“原子变量”?
  • 【vscode】.dart文件没有错误波浪线
  • Dubbo(93)如何在电商系统中应用Dubbo?
  • Power Query精通指南4:M语言(查询结构与值系统)、查询优化、自动刷新
  • rails 8 CSS不起效问题解决
  • 异步数据库事务锁:电商库存扣减的防超卖秘籍
  • 【Linux系统篇】:Linux线程控制基础---线程的创建,等待与终止
  • Tesla的战略变化策略(2010~2024)以及给中国汽车厂家的启发
  • Deformable DETR模型解读(附源码+论文)
  • 【算法基础】快速排序算法 - JAVA
  • Cycleresearcher:通过自动化评审改进自动化研究
  • Python 数据智能实战 (10):智能商品推荐 - LLM “猜你喜欢”
  • v0.6.7/OllamaSetup.exe下载链接
  • SpringSecurity配置(权限认证)
  • 论数据分片技术及其应用
  • 市面上所有大模型apikey获取指南(持续更新中)
  • 进程间通信(IPC)
  • 安卓基础(悬浮窗和摄像)
  • 基于大模型的肾结石诊疗全流程风险预测与方案制定研究报告
  • Oracle无法正常OPEN(四)
  • Spring AI 实战:第一章、Spring AI入门之DeepSeek调用
  • 天翼云ftp服务器搭建详细步骤,ftp服务器路径怎么写?
  • Centos9 安装 RocketMQ5
  • WebSocket分布式实现方案
  • MySQL中的窗口函数
  • Modbus 通讯协议(超详细,简单易懂)
  • Qt 中实现观察者模式(Observer Pattern)