wayne
wayne
发布于 2025-04-22 / 10 阅读
0
0

Spring之我见 - Spring MVC重要组件和基本流程

Spring MVC重要组件和基本流程

Spring MVC重要组件和基本流程

核心组件详解

前端控制器 - DispatcherServlet

  • 作用:所有请求的入口,负责请求分发和协调组件。

public class DispatcherServlet extends HttpServlet {
    // 核心服务方法
    protected void doService(HttpServletRequest request, 
                            HttpServletResponse response) {
        // 请求处理主流程
    }
}

处理器映射 - HandlerMapping

  • 作用:根据请求 URL 匹配对应的处理器(Controller 方法)。

  • 实现类

    • RequestMappingHandlerMapping:处理 @RequestMapping 注解。

    • BeanNameUrlHandlerMapping:根据 Bean 名称匹配 URL。

处理器适配器 - HandlerAdapter

  • 作用:调用具体的处理器方法,并处理参数绑定和返回值。

public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request,
                       HttpServletResponse response, 
                       Object handler) throws Exception;
}
  • 关键实现

    • RequestMappingHandlerAdapter(处理@Controller)

    • HttpRequestHandlerAdapter(处理Servlet API)

  • 参数解析:通过 HandlerMethodArgumentResolver 解析方法参数(如 @RequestParam, @PathVariable)。

视图解析器 - ViewResolver

  • 作用:将逻辑视图名(如 "home")解析为实际视图(如 JSP、Thymeleaf)。

  • 典型实现:InternalResourceViewResolver(JSP)

  • 配置示例

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

JSON响应处理机制

大部分时候我们使用的是JSON作为数据返回,这时候就不是ViewResolver作为返回解析,JSON 返回和视图返回在结果处理阶段完全分离,前者走消息转换器HttpMessageConverter,后者走视图解析器ViewResolver

核心组件 - HttpMessageConverter

public interface HttpMessageConverter<T> {
    boolean canRead/Write(Class<?> clazz, MediaType mediaType);
    T read(Class<? extends T> clazz, HttpInputMessage inputMessage);
    void write(T t, MediaType contentType, 
              HttpOutputMessage outputMessage);
}
  • 常用实现

    • MappingJackson2HttpMessageConverter(JSON)

    • Jaxb2RootElementHttpMessageConverter(XML)

Servlet Filter 和 Spring MVC Interceptor

Servlet Filter(过滤器)

什么是Filter?

Filter是Servlet规范 中定义的,不属于Spring框架。它可以用于对所有的Web请求进行预处理和后处理,比如权限检查、日志记录、字符编码转换等。Filter依赖于Servlet容器(如Tomcat)。

主要特点:

  • 作用范围广:可以过滤所有进入容器的请求,包括静态资源(如.js, .css, .jpg)和动态请求。

  • 与框架无关:只要是Java Web应用,无论是否使用Spring MVC,都可以使用Filter。

  • 在Servlet之前执行:Filter的调用在Servlet被调用之前。

核心方法:

在自定义Filter时,需要实现javax.servlet.Filter接口,并重写其三个方法:

public class MyFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化方法,容器启动时调用
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 1. 在Servlet执行之前的预处理(Pre-processing)
        System.out.println("Filter: 执行预处理");
        
        // 将请求传递给下一个Filter,最终到达Servlet
        chain.doFilter(request, response);
        
        // 2. 在Servlet执行之后的后处理(Post-processing)
        System.out.println("Filter: 执行后处理");
    }

    @Override
    public void destroy() {
        // 销毁方法,容器关闭时调用
    }
}

Spring MVC Interceptor(拦截器)

什么是Interceptor?

Interceptor是Spring MVC框架 自己提供的机制,用于在Controller方法执行的“前后”以及“完成时”进行拦截处理。

主要特点:

  • 作用范围窄:只能拦截DispatcherServlet 分发的请求,也就是Spring MVC的控制器(Controller)请求。它无法拦截静态资源请求。

  • 依赖于Spring框架:需要配置在Spring的上下文中。

  • 可以获取处理器的信息:可以获取到执行请求的Controller对象和处理方法(HandlerMethod)的信息。

核心方法:

自定义Interceptor需要实现org.springframework.web.servlet.HandlerInterceptor接口,或继承HandlerInterceptorAdapter(Spring 5.3之前),主要重写三个方法:

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在Controller方法执行之前调用
        // 返回值:true表示继续执行(调用下一个拦截器或处理器);false则中断执行。
        System.out.println("Interceptor: preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在Controller方法执行之后,但视图渲染之前调用
        System.out.println("Interceptor: postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整个请求结束(视图渲染完毕)之后调用
        // 通常用于资源清理
        System.out.println("Interceptor: afterCompletion");
    }
}


总结

  • Filter 更底层、更通用,适合处理与业务无关的横切逻辑(如字符编码、安全头)。

  • Interceptor 更贴近业务,适合处理与 Controller 相关的逻辑(如登录校验、操作日志)。

  • 执行顺序:Filter(前置) → Interceptor(preHandle) → Controller → Interceptor(postHandle/afterCompletion) → Filter(后置)。


评论