去皮卡多 发表于 2023-12-31 20:56:06

14、SpringMVC之注解配置

14.1、概述


[*]在实际工作中,一般使用配置类和注解代替web.xml和SpringMVC配置文件的功能;
[*]在 Servlet3.0 环境中,容器会在类路径中查找实现了 javax.servlet.ServletContainerInitializer 接口的类,
如果找到了的话,就会用它来配置 Servlet 容器;
[*]Spring 提供了 ServletContainerInitializer这个接口的实现,类名为 SpringServletContainerInitializer,
这个类又会查找实现了 WebApplicationInitializer 接口的类,并将配置的任务交给它们来完成;
[*]Spring3.2 引入了一个便利的 WebApplicationInitializer 基础实现,类名为 AbstractAnnotationConfigDispatcherServletInitializer;
[*]当自定义的类继承了 AbstractAnnotationConfigDispatcherServletInitializer 并将其部署到 Servlet3.0 容器的时候,
容器会自动发现它,并用它来配置 Servlet 上下文。
14.2、环境搭建

14.2.1、在project创建新module

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115153131118-1734705743.png
12.2.2、选择maven

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115153216783-473040985.png
14.2.3、设置module名称和路径

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115153652476-1130067211.png
https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115153707268-1164803551.png
14.2.4、module初始状态

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115155206993-649526791.png
14.2.5、配置打包方式和引入依赖

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115155714152-1990346895.png
注意:默认的打包方式为 jar,为了能配置web资源,需要将打包方式设置为 war
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>online.liaojy</groupId>
    <artifactId>spring_mvc_annotation</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
      
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.1</version>
      </dependency>
      
      <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
      </dependency>
      
      <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
      </dependency>
      
      <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.12.RELEASE</version>
      </dependency>
      
      <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
      </dependency>
    </dependencies>

</project>14.2.6、配置web资源目录

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115160354675-877290418.png
打开Project Structure,选择对应的module,并为该module创建一个web.xml文件
https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115160837872-2016313904.png
注意:web.xml文件需要放到web资源路径(工程路径\src\main\webapp)下
https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115161139613-75417860.png
因为使用配置类和注解来配置 Servlet 上下文,所以 web.xml 不再需要配置。
14.2.7、创建拦截器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115162422602-1149549311.png
package online.liaojy.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author liaojy
* @date 2023/11/15 - 7:22
*/
public class AAAInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

}14.2.8、创建模板目录及页面模板

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115162703808-575593823.png
注意:html要引入thymeleaf的约束:xmlns:th="http://www.thymeleaf.org"
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>

<h1>index.html</h1>

</body>
</html>https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115162959748-1372976697.png
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>错误页面</title>
</head>
<body>

<h1>errorPage.html</h1>

</body>
</html>14.2.9、配置tomcat

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115163518876-494505683.png
https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115163352895-582472451.png
https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231115163439749-1922844806.png
14.3、web.xml的注解配置

14.3.1、创建Spring配置类

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231117000032745-1575118687.png
package online.liaojy.config;

/**
* @author liaojy
* @date 2023/11/16 - 23:59
* 该类用于代替spring的配置文件
*/
public class SpringConfig {

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

}14.3.2、创建SpringMVC配置类

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231117000326756-122979154.png
package online.liaojy.config;

/**
* @author liaojy
* @date 2023/11/17 - 0:02
* 该类用于代替SpringMVC的配置文件
*/
public class SpringMVCConfig {
}14.3.3、创建代替web.xml的初始化类

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231117000940754-844958077.png
package online.liaojy.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

/**
* @author liaojy
* @date 2023/11/17 - 0:04
*/
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    // 指定代替 Spring 配置文件的配置类(可以按功能或需要来划分多个)
    protected Class<?>[] getRootConfigClasses() {
      return new Class[]{SpringConfig.class};
    }

    // 指定代替 SpringMVC 配置文件的配置类(可以按功能或需要来划分多个)
    protected Class<?>[] getServletConfigClasses() {
      return new Class[]{SpringMVCConfig.class};
    }

    // 设置 SpringMVC 的前端控制器 DispatcherServlet 需要处理的请求路径(即 url-pattern )
    protected String[] getServletMappings() {
      return new String[]{"/"};
    }

    // 设置过滤器
    @Override
    protected Filter[] getServletFilters() {

      // 配置编码过滤器
      CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
      characterEncodingFilter.setEncoding("UTF-8");
      characterEncodingFilter.setForceEncoding(true);

      // 配置处理请求方式的过滤器
      // 注意该过滤器所在的包路径为 org.springframework.web.filter.HiddenHttpMethodFilter
      HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();

      // 配置要使用的过滤器
      return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};

    }
}14.4、SpringMVC配置类的详细配置

14.4.1、将类标识为配置类

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119163736927-598473158.png
// @Configurable 注解:将类标识为配置类
@Configurable14.4.2、实现 WebMvcConfigurer 接口

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119163924757-489208072.png
14.4.3、配置扫描组件

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119165718045-1430051518.png
先创建一个需要扫描的包及组件
package online.liaojy.controller;

import org.springframework.stereotype.Controller;

/**
* @author liaojy
* @date 2023/11/19 - 16:56
*/
@Controller
public class TestController {
}https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119170148072-217589459.png
// @ComponentScan 注解:用于扫描指定包的组件
@ComponentScan("online.liaojy.controller")14.4.4、配置默认servlet处理器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119171247696-1008430073.png
    // 配置默认servlet处理器
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
      configurer.enable();
    }14.4.5、配置mvc注解驱动

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119171444945-1013467862.png
// @EnableWebMvc 注解:开启mvc的注解驱动
@EnableWebMvc14.4.6、配置视图控制器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119172142947-851972166.png
    // 配置视图控制器
    public void addViewControllers(ViewControllerRegistry registry) {
      // addViewController 设置视图控制器要处理的请求路径,setViewName 设置匹配请求路径的逻辑视图
      registry.addViewController("/").setViewName("index");
    }14.4.7、配置文件上传解析器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119175628240-1923361367.png
    // 配置文件上传解析器
    // @Bean 注解:用于将所标识方法的返回值作为一个 bean 来进行管理,bean的id为方法名
    @Bean
    public CommonsMultipartResolver multipartResolver(){
      return new CommonsMultipartResolver();
    }14.4.8、配置拦截器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119175724681-2069945011.png
    // 配置拦截器
    public void addInterceptors(InterceptorRegistry registry) {
      AAAInterceptor aaaInterceptor = new AAAInterceptor();
      // addInterceptor 设置要使用的拦截器,
      // addPathPatterns 设置该拦截器要拦截的请求路径( /** 表示所有路径),excludePathPatterns 设置要排除的拦截路径
      registry.addInterceptor(aaaInterceptor).addPathPatterns("/**").excludePathPatterns("/abc");
    }14.4.9、配置异常解析器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119181444580-2125984462.png
    // 配置异常解析器
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

      // 创建 SimpleMappingExceptionResolver 异常解析器,来对控制器方法出现的异常进行自定义异常处理
      SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();

      // 设置异常和错误提示页面的映射关系
      Properties properties = new Properties();
      properties.setProperty("java.lang.ArithmeticException", "errorPage");
      simpleMappingExceptionResolver.setExceptionMappings(properties);

      // 设置共享到域对象中的异常信息的属性名
      simpleMappingExceptionResolver.setExceptionAttribute("exceptionMessage");

      // 添加要使用的异常解析器器
      resolvers.add(simpleMappingExceptionResolver);
    }14.4.10、配置视图解释器

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119183419960-756926025.png
配置视图解释器,无论是通过xml还是配置类都比较复杂;一般直接都是复制配置模板,然后根据实际修改视图前缀及后缀即可
    //配置生成模板解析器
    @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;
    }14.4.11、全配置汇总

package online.liaojy.config;import online.liaojy.interceptor.AAAInterceptor;import org.springframework.beans.factory.annotation.Configurable;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.web.context.ContextLoader;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.multipart.commons.CommonsMultipartResolver;import org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.*;import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;import org.thymeleaf.spring5.SpringTemplateEngine;import org.thymeleaf.spring5.view.ThymeleafViewResolver;import org.thymeleaf.templatemode.TemplateMode;import org.thymeleaf.templateresolver.ITemplateResolver;import org.thymeleaf.templateresolver.ServletContextTemplateResolver;import java.util.List;import java.util.Properties;/** * @author liaojy * @date 2023/11/17 - 0:02 * 该类用于代替SpringMVC的配置文件 */// @Configurable 注解:将类标识为配置类
@Configurable// @ComponentScan 注解:用于扫描指定包的组件
@ComponentScan("online.liaojy.controller")// @EnableWebMvc 注解:开启mvc的注解驱动
@EnableWebMvcpublic class SpringMVCConfig implements WebMvcConfigurer {    // 配置默认servlet处理器
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
      configurer.enable();
    }    // 配置视图控制器
    public void addViewControllers(ViewControllerRegistry registry) {
      // addViewController 设置视图控制器要处理的请求路径,setViewName 设置匹配请求路径的逻辑视图
      registry.addViewController("/").setViewName("index");
    }    // 配置文件上传解析器
    // @Bean 注解:用于将所标识方法的返回值作为一个 bean 来进行管理,bean的id为方法名
    @Bean
    public CommonsMultipartResolver multipartResolver(){
      return new CommonsMultipartResolver();
    }    // 配置拦截器
    public void addInterceptors(InterceptorRegistry registry) {
      AAAInterceptor aaaInterceptor = new AAAInterceptor();
      // addInterceptor 设置要使用的拦截器,
      // addPathPatterns 设置该拦截器要拦截的请求路径( /** 表示所有路径),excludePathPatterns 设置要排除的拦截路径
      registry.addInterceptor(aaaInterceptor).addPathPatterns("/**").excludePathPatterns("/abc");
    }    // 配置异常解析器
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

      // 创建 SimpleMappingExceptionResolver 异常解析器,来对控制器方法出现的异常进行自定义异常处理
      SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();

      // 设置异常和错误提示页面的映射关系
      Properties properties = new Properties();
      properties.setProperty("java.lang.ArithmeticException", "errorPage");
      simpleMappingExceptionResolver.setExceptionMappings(properties);

      // 设置共享到域对象中的异常信息的属性名
      simpleMappingExceptionResolver.setExceptionAttribute("exceptionMessage");

      // 添加要使用的异常解析器器
      resolvers.add(simpleMappingExceptionResolver);
    }    //配置生成模板解析器
    @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;
    }}14.5、测试效果

https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119184100192-1132230243.png
https://img2023.cnblogs.com/blog/2052479/202311/2052479-20231119184127314-1107031619.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 14、SpringMVC之注解配置