目录
(前置工作)创建新的模块springMVC-annotation
2.设置配置类用来代替SpringMVC核心配置文件SpringMVC.config
DispatcherServlet调用各个组件处理请求的过程
2.Spring怎么知道处理mvc开头的标签就调用MvcNamespaceHandler中注册的解析器的呢
注解配置SpringMVC
说明:使用配置类和注解代替web.xml和SpringMVC配置文件的功能,后面的SSM框架整合之后,Spring的配置也不用写
(前置工作)创建新的模块springMVC-annotation
- pom.xml,刷新Maven
<?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>com.atguigu.com</groupId> <artifactId>springMVC-annotation</artifactId> <version>1.0-SNAPSHOT</version> <!--修改Idea默认模块Language Level从5修改成6,否则接口方法会报错--> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>6</source> <target>6</target> </configuration> </plugin> </plugins> </build> <!--工程打包方式,默认是jar,如果这是一个web工程,打包方式为war 当前是一个web工程,因此我们需要为这个Maven工程添加web模块, 模块里面有webapp及webapp里面的web.xml--> <packaging>war</packaging> <!--添加依赖群,当导报成war包时,这些依赖都会被放到webapp目录的 WEB-INF目录中的lib目录下--> <dependencies> <!--添加单个依赖SpringMVC,下面同理.由于 Maven 的传递性, 我们不必将所有需要的包全部配置依赖,而是配置最顶端的依赖,其他靠传递性导入, 意味着只要导入了这个SpringMVC依赖,那么 SpringMVC依赖的依赖也会导入进来,其中就有spring的基础框架jar包: aop、beans、context、core、expression,还有自身web框架jar包 传递性对于其他依赖同理--> <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> <!-- ServletAPI,之前没导入是因为Tomcat自带了Servlet和JSP的jar包, 因此只要配置了tomcat就能使用Servlet,java不自带Servlet的--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <!--依赖范围,表示我们什么地方可以使用这个jar包, 这里设置成provided就是该依赖已被服务器提供,因此编译时 这个依赖都会被放到webapp目录的WEB-INF目录中的lib目录下--> <scope>provided</scope> </dependency> <!-- Spring5和Thymeleaf整合包,是视图技术,控制页面显示内容 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> <!--JackSon依赖,用于SpringMVC处理JSON--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.1</version> </dependency> <!--上传文件需要的Jar包--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> </dependencies> </project>
- 完善web模块,但是不需要web.xml
- 配置Tomcat服务器
1.创建初始化类,代替web.xml
说明:
- 在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类, 如果找到的话就用它来配置Servlet容器(我们使用的Tomcat服务器)。
- Spring提供了这个接口的实现,名为 SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer接口的类并将配置的任务交给它们来完成。
- Spring3.2(我们现在是用的是Spring5.3.1)引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展(继承)了 AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候,容器会自动发现它,并用它来配置Servlet上下文。
- 也就是说Servlet3.2版本之后,容器会这样去找初始化类代替web.xml:
实现javax.servlet.ServletContainerInitializer接口的类SpringServletContainerInitializer-->实现WebApplicationInitializer接口的类AbstractAnnotationConfigDispatcherServletInitializer-->继承了AbstractAnnotationConfigDispatcherServletInitializer的类,这个拓展类就是我们用来代替web.xml配置Servlet上下文
- 在 src\main\java\com\atguigu\mvc\config\WebInit.java 创建一个web初始化类,该类是用来代替Web.xml的web初始化类,配置前端控制器,springMVC\spring的配置文件路径,还有过滤器
package com.atguigu.mvc.config; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.filter.HiddenHttpMethodFilter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import javax.servlet.Filter; /** * 该类是用来代替Web.xml的web初始化类 * 除了配置前端控制器,springMVC\spring的配置文件路径,还有过滤器 */ public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer { /** * 指定根配置,也就是Spring的配置类 * @return 返回值是一个数组,也就是可以有多个配置类 */ @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } /** * 指定ServletC配置,也就是SpringMVC的配置类 * @return 返回值是一个数组,也就是可以有多个配置类 */ @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{WebConfig.class}; } /** * 指定DispatcherServlet前端控制器的映射规则,也就是什么请求会被前端控制器拦截 * @return 返回值是一个数组,也就是可以有多个请求映射路径,规则和Web.xml一样, * "/"表示除了JSP以外的请求都处理 */ @Override protected String[] getServletMappings() { return new String[]{"/"}; } /** * 分别注册CharacterEncodingFilter、HiddenHttpMethodFilter过滤器 * @return 返回值表示多个过滤器,注意过滤器的顺序 */ @Override protected Filter[] getServletFilters() { //设置编码过滤器要支持UTF-8 CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF-8");//设置字符编码为UTF-8 characterEncodingFilter.setForceResponseEncoding(true);//设置响应编码强制遵循如上设置的编码 //不设置接收请求为true是因为底层代码在request并没有设置,因此肯定为true,也就是接收请求编码的一定是强制用如上所设置的编码 //设置隐藏请求方法过滤器,启用除了GET和POST以外的请求 HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};//注意过滤器顺序放置乱码 } }
- 在 src\main\java\com\atguigu\mvc\config\WebConfig.java 创建一个(SpringMVC)配置类待用
package com.atguigu.mvc.config; import org.springframework.beans.factory.annotation.Configurable; /** * 该类用来代替SpringMVC核心配置文件SpringMVC.config */ @Configurable//标识该类是一个(SpringMVC)配置类 public class WebConfig { }
- 在 src\main\java\com\atguigu\mvc\config\SpringConfig.java 创建一个(Spring)配置类待用
package com.atguigu.mvc.config; import org.springframework.beans.factory.annotation.Configurable; /** * 因为并没有使用SSM的整合,所以Spring的配置就不写了 */ @Configurable//标识该类是一个(Spring)配置类 public class SpringConfig { }
2.设置配置类用来代替SpringMVC核心配置文件SpringMVC.config
说明:不演示文件上传是否实现
- 在SpringMVC配置类 src\main\java\com\atguigu\mvc\config\WebConfig.java 中添加如下配置实现扫描组件、配置视图解析器、视图控制器view-controller、默认Servlet default-servlet-handler(解决静态资源的)、MVC注解驱动、文件上传解析器、异常处理、拦截器
package com.atguigu.mvc.config; import com.atguigu.mvc.interceptor.TestInterceptor; 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; /** * 该类用来代替SpringMVC核心配置文件SpringMVC.config * 实现扫描组件、配置视图解析器、视图控制器view-controller、 * 默认Servlet default-servlet-handler(解决静态资源的)、 * MVC注解驱动、文件上传解析器、异常处理、拦截器 */ @Configurable//标识该类是一个(SpringMVC)配置类 @ComponentScan("com.atguigu.mvc")//扫描组件,设置成员参数value来指定包路径 @EnableWebMvc//开启MVC注解驱动 public class WebConfig implements WebMvcConfigurer {//WebMvcConfigurer接口里面有很多我们需要的配置SpringMVC的功能 /* 设置视图解析器,从最里面对象开始设置,视图解析器是一个Bean,所以不需要实现任何的接口和继承任何的类 */ /** * 1.配置生成模板解析器 * @return 返回值是ITemplateResolver接口的实现类SpringResourceTemplateResolver */ @Bean//这个注解表示该方法的返回值就是IOC容器中的一个Bean public ITemplateResolver templateResolver() { //如果是web工程,就需要用WebApplicationContext接口的实现类 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; } /** * 2.生成模板引擎并为模板引擎注入模板解析器 * @param templateResolver 已经配置到IOC容器的模板解析器.这个形参的值是spring在IOC容器中找到同类型的Bean, * 然后通过类型注入进去的,是spring自动装配功能 * @return */ @Bean public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); return templateEngine; } /** * 3.生成视图解析器并未解析器注入模板引擎 * @param templateEngine 已经配置到IOC容器的模板引擎.这个形参的值是spring在IOC容器中找到同类型的Bean, * 然后通过类型注入进去的,是spring自动装配功能 * @return */ @Bean public ViewResolver viewResolver(SpringTemplateEngine templateEngine) { ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setCharacterEncoding("UTF-8"); viewResolver.setTemplateEngine(templateEngine); return viewResolver; } /* 通过快捷键"ctr+o"重写方法如下方法,配置默认的Servlet处理静态资源 */ /** * 下面的方法相当于<mvc:default-servlet-handler/> * @param configurer 用于开启或者关闭默认Servlet处理,默认是关闭的 */ @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { con