SpringMVC中那些Java Config

简单来讲,就是使用Java 配置替代以的xml配置。MVC Java配置和MVC XML namespace提供了适用于大多数应用程序的默认配置,并提供了一个用于自定义的配置API。

【1】启用MVC Configuration

在Java配置中,你可以使用@EnableWebMvc注解启用MVC configuration。如下所示:

@Configuration
@EnableWebMvc
public class WebConfig {
}

在XML配置中,你可以使用注解来启用MVC配置。如下所示:


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    


前面的示例注册了大量SpringMVC基础结构bean,并适应类路径上可用的依赖项(例如,JSON、XML和其他的有效负载转换器)。

【2】MVC配置API

在Java 配置中 你可以实现WebMvcConfigurer 接口,如下所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    // Implement configuration methods...
}

WebMvcConfigurer接口提供了一系列回调函数供你自定义配置。接口源码与说明如下:

public interface WebMvcConfigurer {

     //帮助配置HandlerMapping路径匹配选项,例如是否使用解析的PathPatterns或与PathPatterns匹配的字符串模式,
     //是否匹配尾部斜杠等。
    default void configurePathMatch(PathMatchConfigurer configurer) {
    }

     //配置内容协商/转换
    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }

    /**
     * Configure asynchronous request handling options.
     */
     //配置异步请求处理
    default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    }


     //配置一个处理器处理仍旧未被处理的请求,通常是转发哦到Servlet容器的"default"servlet
     //这方面的一个常见用例是DispatcherServlet映射到“/”从而覆盖Servlet容器对静态资源的默认处理。
    default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    }


     //注册额外的Converters和Formatters
    default void addFormatters(FormatterRegistry registry) {
    }


     //添加SpringMVC生命周期拦截器,用于控制器方法调用和资源处理程序请求的预处理和后处理。
     //可以注册拦截器以应用于所有请求,也可以将拦截器限制为URL 的子集。
    default void addInterceptors(InterceptorRegistry registry) {
    }

     添加处理程序以处理静态资源,例如web应用程序根目录下、classpath下和其他位置下的图像、js和css文件
    default void addResourceHandlers(ResourceHandlerRegistry registry) {
    }


     //配置跨域请求处理
    default void addCorsMappings(CorsRegistry registry) {
    }

    
     //配置预先配置了响应状态代码和/或视图的简单自动控制器,以呈现响应主体。
     //这在不需要自定义控制器逻辑的情况下非常有用,例如,呈现主页、执行简单的站点URL重定向、
     //返回包含HTML内容的404状态、返回不包含任何内容的204状态等等。
    default void addViewControllers(ViewControllerRegistry registry) {
    }

     //配置视图解析器,将从控制器返回的基于字符串的视图名称转换为具体的org.springframework.web.servlet.view实现,
     //以便使用执行渲染。
    default void configureViewResolvers(ViewResolverRegistry registry) {
    }

     //添加解析器以支持自定义控制器方法参数类型。
    //这不会覆盖解析处理程序方法参数的内置支持。
    //要自定义参数解析的内置支持,请直接配置RequestMappingHandlerAdapter
    default void addArgumentResolvers(List resolvers) {
    }

     //添加处理器以支持自定义控制器方法返回值类型。
     //这不会覆盖springMVC对返回值处理的内置支持,如果想覆盖可以直接配置RequestMappingHandlerAdapter 
    default void addReturnValueHandlers(List handlers) {
    }

     //配置HttpMessageConverters用于从request读取并写入response。如果没有添加converter,将会注册一系列默认的。
     //注意,通过该方法添加Converter,将会关闭默认converters的注册。如果只是想添加额外的Converter,
     //建议使用extendMessageConverters方法
    default void configureMessageConverters(List<HttpMessageConverter> converters) {
    }

     //注册默认converters后,运行你进行添加自定义转换器(也可以修改converters,通常不建议)
    default void extendMessageConverters(List<HttpMessageConverter> converters) {
    }

     //配置异常解析器。给定的resolvers开始可能为空,如果为空,框架会配置一系列默认的解析器,
     //参考WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers(List,ContentNegotiationManager)
     //或者,如果列表中添加了任何异常解析程序,则应用程序将有效地接管并必须提供完全初始化的异常解析程序。
     //你可以选择使用extendHandlerExceptionResolvers方法,该方法允许你对默认配置的异常解析器进行扩展或修改
    default void configureHandlerExceptionResolvers(List resolvers) {
    }
    
     //扩展或修改默认配置的异常解析器列表
    default void extendHandlerExceptionResolvers(List resolvers) {
    }

     //提供一个自定义的Validator替换掉框架默认创建的
     //在JSR-303中,默认实现是org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean
     //返回值为null表示使用默认配置。
    @Nullable
    default Validator getValidator() {
        return null;
    }

    /**
     * Provide a custom {@link MessageCodesResolver} for building message codes
     * from data binding and validation error codes. Leave the return value as
     * {@code null} to keep the default.
     */
     //提供自定义MessageCodesResolver,用于从数据绑定和验证错误代码生成消息代码。
     //返回值为null表示使用默认配置。
    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }

}

【3】类型转换

默认情况下,会配置各种数字和日期类型的格式化器,并支持通过字段上的@NumberFormat@DateTimeFormat进行自定义。

如下实例,在Java config中注册自定义formatters 格式化器和converters类型转换器:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // ...
    }
}

类似的,xml中配置如下:


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    

    <bean id="conversionService"
            class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        
            
                
            
        
        
            
                
                
            
        
        
            
                
            
        
    


默认情况下,SpringMVC在解析和格式化日期值时考虑请求区域设置。这适用于将日期表示为“input”表单字段的字符串的表单。但是,对于”date” and “time” form fields,浏览器使用HTML规范中定义的固定格式。对于这种情况,日期和时间格式可以按如下方式自定义:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setUseIsoFormat(true);
        registrar.registerFormatters(registry);
    }
}

【4】Validation

默认情况下,如果类路径上存在Bean 校验器(例如Hibernate Validator),则LocalValidatorFactoryBean将注册为全局验证程序,以便@Valid@Validated 与控制器方法参数一起使用。v

在Java 配置中,你可以定义一个全局的Validator 实例,如下所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public Validator getValidator() {
        // ...
    }
}

等同的xml配置如下:


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    


你也可以选择局部注册Validator ,如下所示:

@Controller
public class MyController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new FooValidator());
    }
}

如果需要在某处注入LocalValidatoryFactoryBean,请创建一个bean并用@Primary标记它,以避免与MVC配置中声明的bean冲突。

【5】拦截器

在Java配置中,您可以注册拦截器以应用于传入的请求,如下例所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
        registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
        registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
    }
}

等同的xml配置如下:


    
    
        
        
        
    
    
        
        
    

【6】Content Types

您可以配置SpringMVC如何根据请求确定请求的内容类型(例如,Accept头、URL路径扩展、查询参数等)。

默认情况下,值检测Accept 头。如果必须使用基于URL的内容类型解析,请考虑在路径扩展上使用查询参数策略。

在Java配置中,您可以自定义请求的内容类型解析,如下例所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.mediaType("json", MediaType.APPLICATION_JSON);
        configurer.mediaType("xml", MediaType.APPLICATION_XML);
    }
}

等同的xml配置如下所示:




    
        
            json=application/json
            xml=application/xml
        
    

【7】Message Converters

在Java config中你可以自定义HttpMessageConverter 通过覆盖configureMessageConverters()方法(替换SpringMVC提供的默认converters )或者覆盖extendMessageConverters()方法(自定义默认的converters或者额外添加converters)。

以下示例使用自定义的ObjectMapper(而不是默认的ObjectMapper)添加XML和Jackson JSON转换器:

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
                .indentOutput(true)
                .dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
                .modulesToInstall(new ParameterNamesModule());
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
    }
}

在前面的示例中,Jackson2ObjectMapperBuilder 用于为MappingJackson2HttpMessageConverter 和MappingJackson2XmlHttpMessageConverter 创建通用配置,启用indentation 、自定义日期格式和 jackson-module-parameter-names模块的注册,它增加了对访问参数名的支持(Java8中添加的一个特性)。

此生成器自定义Jackson的默认属性,如下所示:

DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 被禁用

MapperFeature.DEFAULT_VIEW_INCLUSION 被禁用

如果在类路径上检测到以下知名模块,它还会自动注册这些模块:

jackson-datatype-joda: Support for Joda-Time types.

jackson-datatype-jsr310: Support for Java 8 Date and Time API types.

jackson-datatype-jdk8: Support for other Java 8 types, such as Optional.

jackson-module-kotlin: Support for Kotlin classes and data classes.

启用Jackson XML支持的缩进需要woodstox-core-asl依赖项和jackson-dataformat-xml 依赖项。

还有其他有趣的Jackson模块:

jackson-datatype-money: Support for javax.money types (unofficial module).

jackson-datatype-hibernate: Support for Hibernate-specific types and properties (including lazy-loading aspects).

等同的xml配置如下所示:


    
        
            
        
        
            
        
    


<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
      p:indentOutput="true"
      p:simpleDateFormat="yyyy-MM-dd"
      p:modulesToInstall="com.fasterxml.jackson.module.paramnames.ParameterNamesModule"/>


【8】 View Controllers

这是定义ParameterableViewController的快捷方式,该控制器在调用时立即转发到视图。可以在静态情况下使用它,也就是当视图生成响应之前没有Java控制器逻辑运行。

以下Java配置示例将请求/转发到名为home的视图:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("home");
    }
}

等同的xml配置如下所示:

当一个标注了@RequestMapping方法匹配到URL,则view controller不能再处理该URL。

如果@RequestMapping方法映射到任何HTTP方法的某个URL,则视图控制器不能用于处理同一URL。这是因为URL与带注解控制器的匹配被认为是端点所有权的足够强的声明,因此可以将405(METHOD_NOT_ALLOWED)、415(UNSUPPORTED_MEDIA_TYPE)或类似响应发送到客户端以帮助调试。因此,建议避免在带注解的控制器和视图控制器view controller之间拆分URL处理。

【9】 视图解析器

MVC configuration 简化了视图解析器的注册。以下Java配置示例通过使用JSPJackson作为JSON呈现的默认视图来配置内容协商视图解析:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.enableContentNegotiation(new MappingJackson2JsonView());
        registry.jsp();
    }
}

等同的xml配置如下:


    
        
            
        
    
    

但是,请注意,FreeMarker、Tiles、Groovy Markup和script templates也需要配置底层视图技术。

MVC命名空间提供专用元素。以下示例适用于FreeMarker:


    
        
            
        
    
    



    

在Java配置中,您可以添加相应的Configurer bean,如下例所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.enableContentNegotiation(new MappingJackson2JsonView());
        registry.freeMarker().cache(false);
    }

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("/freemarker");
        return configurer;
    }
}

【10】Static Resources

此选项提供了一种方便的方法,可以从Resource-based 的位置列表中快速访问静态资源。

在下一个示例中,给定一个以/resources开头的请求,然后在web应用程序根目录下/public或在classpath:/static/目录下的类路径上查找和提供静态资源。

这些资源的使用期限为一年,以确保最大限度地利用浏览器缓存,并减少浏览器发出的HTTP请求。最后Last-Modified 的信息是从Resource#lastModified推导出来的,因此HTTP请求需要支持“Last-Modified”头。

Java 配置实例如下:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
            .addResourceLocations("/public", "classpath:/static/")
            .setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
    }
}

等同的xml配置如下:

<mvc:resources mapping="/resources/**"
    location="/public, classpath:/static/"
    cache-period="31556926" />

资源处理程序还支持ResourceResolver 实现链和ResourceTransformer 实现链,您可以使用它们创建用于处理优化资源的工具链。

您可以基于从内容、固定应用程序版本或其他内容计算的MD5哈希将VersionResourceResolver用于已版本化的资源URL。ContentVersionStrategy (MD5哈希)是一个不错的选择 — 除了一些值得注意的例外,比如模块加载器使用的JavaScript资源。

下面实例展示了在Java配置如何使用VersionResourceResolver :

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/public/")
                .resourceChain(true)
                .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
    }
}

等同的xml配置如下所示:


    
        
            
                
            
        
    

然后,您可以使用ResourceUrlProvider 重写URL并应用整个解析程序和转换器链 — 例如,插入版本。MVC配置提供了一个ResourceUrlProvider bean,以便可以将其注入到其他配置中。您还可以使用ResourceUrlEncodingFilter 对Thymeleaf、JSP、FreeMarker和其他依赖HttpServletResponse#encodeURL的URL标记的文件进行透明重写。

请注意,当同时使用EncodedResourceResolver (例如,用于服务Gzip或brotli编码的资源)和VersionResourceResolver时,必须按此顺序注册它们。这确保了基于内容的版本始终基于未编码的文件可靠地计算。

WebJars 还通过WebJarsResourceResolver 得到支持,当org.webjars:webjars-locator-core核心库出现在类路径上时,WebJarsResourceResolver资源解析器会自动注册。解析器可以重写URL以包含jar的版本,还可以匹配没有版本的传入URL — 例如,从/jquery/jquery.min.js到/jquery/1.2.0/jquery.min.js。

【11】Default Servlet

SpringMVC允许将DispatcherServlet映射到/(从而覆盖容器的默认Servlet的映射),同时仍然允许容器的默认Servlet处理静态资源请求。它使用/**的URL映射配置DefaultServletHttpRequestHandler,并且相对于其他URL映射具有最低优先级。

DefaultServletHttpRequestHandler转发所有请求到default Servlet.因此,它必须在所有其他URL HandlerMappings的顺序中保持最后一个。如果使用,就是这种情况。或者,如果设置自己的自定义HandlerMapping实例,请确保将其order属性设置为低于DefaultServletHttpRequestHandler的值,即Integer.MAX_VALUE。DefaultServletHttpRequestHandler中处理请求方法如下所示:

@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

Assert.state(this.servletContext != null, "No ServletContext set");
RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName);
if (rd == null) {
    throw new IllegalStateException("A RequestDispatcher could not be located for the default servlet '" +
            this.defaultServletName + "'");
}
rd.forward(request, response);
}

以下示例显示如何使用默认设置启用该功能:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

等同的xml配置如下所示:

重写/Servlet映射的注意事项是,必须按名称而不是路径检索默认Servlet的RequestDispatcher。DefaultServletHttpRequestHandler 尝试在启动时自动检测容器的默认Servlet,使用大多数主要Servlet容器(包括Tomcat、Jetty、GlassFish、JBoss、Resin、WebLogic和WebSphere)的已知名称列表。如果默认Servlet已使用不同的名称进行自定义配置,或者如果在默认Servlet名称未知的情况下使用不同的Servlet容器,则必须显式提供默认Servlet的名称,如以下示例所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable("myCustomDefaultServlet");
    }
}

下示例显示了如何在XML中实现相同的配置:

【12】Path Matching

您可以自定义与路径匹配和URL处理相关的选项。更多详情参考PathMatchConfigurer.

以下示例显示如何在Java配置中自定义路径匹配:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer
            .setPatternParser(new PathPatternParser())
            .addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
    }

    private PathPatternParser patternParser() {
        // ...
    }
}

以下示例显示了如何在XML中实现相同的配置:


    <mvc:path-matching
        trailing-slash="false"
        path-helper="pathHelper"
        path-matcher="pathMatcher"/>




【13】Advanced Java Config

@EnableWebMvc导入了DelegatingWebMvcConfiguration 其作用如下:

  • 为SpringMVC应用程序提供默认Spring配置
  • 检测并委托WebMVCConfiguer实现以自定义该配置。

对于高级模式,您可以删除@EnableWebMvc并直接从DelegatingWebMvcConfiguration配置扩展,而不是实现WebMVC配置,如下例所示:

@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration {

    // ...
}

您可以在WebConfig中保留现有方法,但现在还可以覆盖基类中的bean声明,并且在类路径上仍然可以有任意数量的其他WebMVCConfiguer实现。

【14】Advanced XML Config

MVC命名空间没有高级模式。如果需要在bean上自定义一个不能更改的属性,可以使用Spring ApplicationContextBeanPostProcessor 生命周期挂钩,如下例所示:

@Component
public class MyPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        // ...
    }
}

注意,您需要将MyPostProcessor声明为bean,可以用XML显式地声明,也可以通过声明使其被检测。

【15】创建初始化类,代替web.xml

在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。 Spring提供了这个接口的实现,名为org.springframework.web.SpringServletContainerInitializer。

SpringServletContainerInitializer这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。

Spring3.2引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候,容器会自动发现它,并用它来配置Servlet上下文。

WebApplicationInitializer实现类图示

//web工程的初始化类,用来代替web.xml
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    /**
     * 指定spring的配置类
     * @return
     */
    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    /**
     * 指定springMVC的配置类
     * @return
     */
    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    /**
     * 指定DispatcherServlet的映射规则,即url-pattern
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 注册过滤器
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceResponseEncoding(true);
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
    }
}

创建SpringConfig配置类,代替spring的配置文件

ssm整合之后,spring的配置信息写在此类中

@Configuration
public class SpringConfig {
//...
}

【16】创建WebConfig配置类,代替SpringMVC的配置文件

/**
 * 代替SpringMVC的配置文件:
 * 1、扫描组件   2、视图解析器     3、view-controller    4、default-servlet-handler
 * 5、mvc注解驱动    6、文件上传解析器   7、异常处理      8、拦截器
 */
//将当前类标识为一个配置类
@Configuration
//1、扫描组件
@ComponentScan("com.mvc.controller")
//5、mvc注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    //4、default-servlet-handler
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    //8、拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        TestInterceptor testInterceptor = new TestInterceptor();
        registry.addInterceptor(testInterceptor).addPathPatterns("/**");
    }

    //3、view-controller
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/hello").setViewName("hello");
    }

    //6、文件上传解析器
    @Bean
    public MultipartResolver multipartResolver(){
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
        return commonsMultipartResolver;
    }

    //7、异常处理
    @Override
    public void configureHandlerExceptionResolvers(List resolvers) {
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
        Properties prop = new Properties();
        prop.setProperty("java.lang.ArithmeticException", "error");
        exceptionResolver.setExceptionMappings(prop);
        exceptionResolver.setExceptionAttribute("exception");
        resolvers.add(exceptionResolver);
    }

    //配置生成模板解析器
    @Bean
    public ITemplateResolver templateResolver() {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        // ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(
                webApplicationContext.getServletContext());
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    //生成模板引擎并为模板引擎注入模板解析器
    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }

    //生成视图解析器并未解析器注入模板引擎
    @Bean
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setCharacterEncoding("UTF-8");
        viewResolver.setTemplateEngine(templateEngine);
        return viewResolver;
    }

}

发表评论