Spring 4 学习笔记7:MVC 配置(JAVA方式)

本文是《Spring in Action》第四版的学习笔记,重点介绍了Spring MVC的配置,包括请求生命周期、配置Spring MVC、自定义DispatcherServlet、配置额外的servlets和filters、开启Spring MVC支持、静态文件处理、控制器、获取请求输入、视图解析、异常处理以及面向资源的控制器等内容。通过Java配置方式展示了如何处理请求、配置web应用、自定义DispatcherServlet以及处理静态文件和异常。
摘要由CSDN通过智能技术生成

《Spring in Action》4th Edition 学习笔记

Spring MVC 能处理从 请求 - 处理 - 返回 的所有流程,来看看它是如何工作的。

请求生命周期

Request LifeTime

  1. front controller也就是DispatcherServlet接受到请求
  2. DispatcherServlet根据请求url映射到对应的 controller
  3. DispatcherServlet发送请求到对应的 controller
  4. controller 处理请求,把需要返回的数据放入 model 中,然后指定 view name,把包含这些数据的 request 发送回 DispatcherServlet
  5. DispatcherServlet 生成一个 view resolver 处理逻辑视图名称
  6. request 到达 view implementation
  7. 现在,view implementation 将使用 request 传入的 modal data 去渲染视图(request 的工作完成了),然后将视图写入 response object,返回给 client 端

配置 Spring MVC

使用 Servlet 3 规范,可以使用 java 来配置 servlet,而不仅仅是 xml 文件。这里主要介绍如何使用 java 配置 web 应用和 spring MVC。

package spittr.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import spittr.web.WebConfig;

public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
   

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] { RootConfig.class };
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { WebConfig.class };
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }

}

Servlet 3.0 规范和 Spring DispatcherServlet 配置
在 Servlet 3.0 的环境中,容器会在 classpath 中寻找继承了 javax.servlet.ServletContainerInitializer 接口的类,用它来配置 servlet 容器。
Spring 提供了一个继承这个接口的类 SpringServletContainerInitializer,在这个类中,它会寻找任何继承了 WebApplicationInitializer 接口的类并用其来配置 servlet 容器。Spring 3.2 提供了一个继承了 WebApplicationInitializer 接口的基类 AbstractAnnotationConfigDispatcherServletInitializer。所以,你的 servlet 配置类只需要继承 AbstractAnnotation-ConfigDispatcherServletInitializer,就会被发现而用于 servlet 容器的配置。

DispatcherServlet VS ContextLoaderListener

在 Spring MVC 中存在两种应用上下文:DispatcherServlet 创建的和拦截器 ContextLoaderListener 创建的上下文:

  • DispatcherServlet:加载包含 web 组件的 bean,比如 controllers,view resolvers 和 hanlder mappings。
  • ContextLoaderListener:加载其他 bean,通常是一些中间层和数据层的组件(比如数据库配置 bean 等)。

AbstractAnnotationConfigDispatcherServletInitializerDispatcherServletContextLoaderListener 都会被创建,而基类中的方法就可用来创建不同的应用上下文:

  • getServletConfigClasses():定义 DispatcherServlet 应用上下文中的 beans
  • getRootConfigClasses():定义拦截器 ContextLoaderListener 应用上下文中的 beans

Note:为了使用 AbstractAnnotationConfigDispatcherServletInitializer 必须保证 web 服务器支持 Servlet 3.0 标准(如 tomcat 7 或更高版本) 。

自定义 DispatcherServlet 配置

因为我们使用 AbstractAnnotationConfigDispatcherServletInitializer 来配置 DispatcherServlet,所以可以通过 customizeRegistration() 方法来自定义 DispatcherServlet。原文如下:

One such method is customizeRegistration(). After AbstractAnnotationConfigDispatcherServletInitializer registers DispatcherServlet with the servlet
container, it calls the customizeRegistration() method, passing in the ServletRegistration.Dynamic that resulted from the servlet registration. By overriding
customizeRegistration(), you can apply additional configuration to DispatcherServlet.

通过 ServletRegistration.Dynamic 参数配置 DispatcherServlet 的 load-on-startup 优先级 setLoadOnStartup(int loadOnStartup),设置初始化参数 setInitParameters() 等。具体查看文档 ServletRegistration.Dynamic

配置额外的 servlets 和 filters

使用 java 配置 servlet 的一个好处(不同于 web.xml)就是:可以定义任意数量的初始化类。所以,如果需要定义额外的 servlets 或 filters,只需要创建额外的初始化类。在 Spring MVC 中可以通过继承 WebApplicationInitializer 接口来实现。

接下来,我们定义一个新的 servlet:

package com.myapp.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import com.myapp.MyServlet;

public class MyServletInitializer implements WebApplicationInitializer {
   

    @Override
    public void onStartup(ServletContext throws ServletException {
        Dynamic myServlet = servletContext.addServlet("myServlet", MyServlet.class);
        myServlet.addMapping("/custom/**");
    }

}

当然,你也可以用来定义 filters 和 listeners:

@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
    // 定义filter
    javax.servlet.FilterRegistration.Dynamic filter =
            servletContext.addFilter("myFilter", MyFilter.class);
    filter.addMappingForUrlPatterns(null, false, "/custom/*");

}

如果你需要为 DispatcherServlet 添加 filter 的话,就不用这么麻烦了,你只要重写 AbstractAnnotationConfigDispatcherServletInitializer 类的 getServletFilters() 方法就行了:

@Override
protected Filter[] getServletFilters() {
    return new Filter[] { new MyFilter() };
}

不需要 mapping,因为会自动 mapping 到 DispatcherServlet 上,通过返回多个 filter,可以添加多个 filter。

开启 Spring MVC 支持

Spring 使用如下方法开启 MVC 的支持:

  • @EnableWebMvc 注解(JavaConfig):和 @Configuration 注解一起使用
  • <mvc:annotation-driven /> 元素(XML 配置)

开启 MVC 支持,它会从 WebMvcConfigurationSupport 导入 Spring MVC 的配置,会在处理请求时加入注解的支持(比如 @RequestMapping@ExceptionHandler等注解)。

如果需要自定义配置,从 @EnableWebMvc文档上来看,需要继承 @WebMvcConfigurer 接口或者继承基类 WebMvcConfigurerAdapter(它继承了 @WebMvcConfigurer 接口,但是用空方法实现)。所以,覆盖相应的方法就能实现 mvc 配置的自定义。

那么,我们需要在 web mvc 配置中做哪些事情呢:

  • 开启 ComponentScan
  • View Resolver(视图解析)
  • 静态文件处理

View Resolver 将在后面介绍,这里先讨论如何处理静态文件(html, css, js)

静态文件处理

Spring 可以有两种方式处理静态文件:

  • 转发到默认的 web 服务器的 servlet 处理(比如 tomcat 来处理)
  • 使用 Spring ResourceHandler 处理

使用这两种办法都需要继承 WebMvcConfigurerAdapter 基类,覆盖其中相应的方法实现。

默认 Servlet 处理
@Override
public 
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值