十三、注解配置SpringMVC
使用配置类和注解代替web.xml和SpringMVC配置文件的功能
1、创建WebInit初始化类,代替web.xml
在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerlnitializer接口的类,如果找到的话就用它来配置Servlet容器。
Spring提供了这个接口的实现,名为SpringServletContainerlnitializer,这个类反过来又会查找实现WebApplicationlnitializer的类并将配置的任务交给它们来完成。Spring3.2引入了一个便利的WebApplicationInitializer甚础实现,名为AbstractAnnotationConfigDispatcherServletlnitializer,当我们的类 扩展了AbstractAnnotationConfigDispatcherServletinitializer并将其部署到Servlet3.0容器的时侯,容器会自动 发现它,并用它来配置Servlet上下文。
实现步骤:
1)新建模块SpringMVC-注解配置SpringMVC
2)pom.xml中导入依赖
<groupId>com.atguigu.mvc</groupId> <artifactId>SpringMVC-注解配置SpringMVC</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <!--导入依赖--> <dependencies> <!--SpringMVC依赖--> <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--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--Spring和Thymeleaf整合包--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> <!--jackson依赖--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.4</version> </dependency> <!--fileupload依赖--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> </dependencies>
3)使用注解配置SpringMVC时,不再需要设置web.xml,因此直接在main目录下新建webapp目录,然后再在webapp目录下新建WEB-IBF目录即可
4)在java目录下新建com/atguigu/mvc/config包,用来存放配置类,然后在config包下新建WebInit类用来代替web.xml,并配置:
//web工程的初始化类,用来代替web.xml public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer { //重写(快捷键:ctrl+O)AbstractAnnotationConfigDispatcherServletInitializer类方法 /** * 指定Spring的配置类 */ @Override protected Class<?>[] getRootConfigClasses() { return new Class[0]; } /** * 指定SpringMVC的配置类 */ @Override protected Class<?>[] getServletConfigClasses() { //Class[]表示创建一个Class类的数组 //Class[]{SpringConfig.class}表示将SpringConfig类放在Class数组中 return new Class[0]; } /** * 指定DispatcherServlet的映射规则,即url-pattern */ @Override protected String[] getServletMappings() { return new String[0]; } }
5)在config包下新建SpringConfig类。
6)在config包下新建WebConfig类。
7)由于需要配置SpringMVC文件,所以还要在WebInit类中配置SpringConfig类、WebConfig类和url-pattern,作为返回值:
/** * 指定Spring的配置类 */ @Override protected Class<?>[] getRootConfigClasses() { //Class[]表示创建一个Class类的数组 //Class[]{SpringConfig.class}表示将SpringConfig类放在Class数组中 return new Class[]{SpringConfig.class}; } /** * 指定SpringMVC的配置类 */ @Override protected Class<?>[] getServletConfigClasses() { //Class[]表示创建一个Class类的数组 //Class[]{WebConfig.class}表示将WebConfig类放在Class数组中 return new Class[]{WebConfig.class}; } /** * 指定DispatcherServlet的映射规则,即url-pattern */ @Override protected String[] getServletMappings() { //设置url=pattern为"/",作为返回值 return new String[]{"/"}; }
8)在WebInit类中配置过滤器
/** * 注册过滤器 */ @Override protected Filter[] getServletFilters() { //设置编码过滤器CharacterEncodingFilter CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); //设置编码方式 characterEncodingFilter.setEncoding("UTF-8"); //设置响应编码方式 characterEncodingFilter.setForceResponseEncoding(true); //设置HiddenHttpMethodFilter过滤器 HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter}; }
9)最终WebInit类的配置:
//web工程的初始化类,用来代替web.xml public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer { //重写(快捷键:ctrl+O)AbstractAnnotationConfigDispatcherServletInitializer类方法 /** * 指定Spring的配置类 */ @Override protected Class<?>[] getRootConfigClasses() { //Class[]表示创建一个Class类的数组 //Class[]{SpringConfig.class}表示将SpringConfig类放在Class数组中 return new Class[]{SpringConfig.class}; } /** * 指定SpringMVC的配置类 */ @Override protected Class<?>[] getServletConfigClasses() { //Class[]表示创建一个Class类的数组 //Class[]{WebConfig.class}表示将WebConfig类放在Class数组中 return new Class[]{WebConfig.class}; } /** * 指定DispatcherServlet的映射规则,即url-pattern */ @Override protected String[] getServletMappings() { //设置url=pattern为"/",作为返回值 return new String[]{"/"}; } /** * 注册过滤器 */ @Override protected Filter[] getServletFilters() { //设置编码过滤器CharacterEncodingFilter CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); //设置编码方式 characterEncodingFilter.setEncoding("UTF-8"); //设置响应编码方式 characterEncodingFilter.setForceResponseEncoding(true); //设置HiddenHttpMethodFilter过滤器 HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter}; } }
2、创建SpringConfig配置类,代替SpringMVC的配置文件
3、创建WebConfig配置类,代替springMVC.xml
1)在WEB-INF目录下新建templates目录,用于存放html文件。然后在templates目录下新建index.html作为首页
<h1>首页</h1>
再在templates目录下新建hello.html,用来测试视图控制器
<h1>hello</h1>
再在templates目录下新建error.html,用来测试异常处理
出现错误 <!--获取放在请求域中的异常信息--> <p th:text="${exception}"></p>
2)在mvc包下新建interceptor包,用于存放拦截器。然后在interceptor包下新建TestInterceptor类,并配置:
public class TestInterceptor implements HandlerInterceptor { //preHandle:在控制器方法执行之前执行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("TestInterceptor-->preHandle"); //返回false表示拦截,返回true表示放行 return true; } //postHandle:在控制器方法执行之后执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } //afterCompletion:在渲染视图完毕后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
3)在mvc包下新建controller包,用于存放控制器。然后在controller包下新建TestController类,并配置:
@Controller public class TestController { //首页 @RequestMapping("/") public String index(){ return "index"; } //异常处理测试 @RequestMapping("/testException") public String testException(){ System.out.println(1/0); return "error"; } }
4)配置WebConfig类:
/** * WebConfig用来代替SpringMVC的配置文件: * 1.扫描组件 * 2.视图解析器 * 3.视图控制器view-controller * 4.静态资源驱动default-servlet-handler * 5.MVC注解驱动 * 6.文件上传解析器 * 7.拦截器 * 8.异常处理 */ //@Configuration:将当前类标识为配置类 @Configuration //扫描组件 @ComponentScan("com.atguigu.mvc.controller") //开启MVC注解驱动 @EnableWebMvc //配置静态资源驱动default-servlet-handler需要对类配置WebMvcConfigurer接口 public class WebConfig implements WebMvcConfigurer { //配置静态资源驱动default-servlet-handler //重写(快捷键Ctrl+O)configureDefaultServletHandling方法 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { //开启配置 configurer.enable(); } //配置拦截器 //重写(快捷键Ctrl+O)addInterceptors方法 public void addInterceptors(InterceptorRegistry registry) { //添加并配置TestInterceptor拦截器 TestInterceptor testInterceptor = new TestInterceptor(); //添加拦截器的拦截路径,'/**'表示多层内的所有请求,'/*'表示一层内的所有请求 registry.addInterceptor(testInterceptor).addPathPatterns("/**"); } //配置视图控制器view-controller //重写(快捷键Ctrl+O)addViewControllers方法 public void addViewControllers(ViewControllerRegistry registry) { //设置路径和视图名称 registry.addViewController("/hello").setViewName("hello"); } //配置文件上传解析器 @Bean public MultipartResolver multipartResolver(){ CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); return commonsMultipartResolver; } //配置异常解析器 public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver(); Properties prop = new Properties(); //设置异常的键key和值value prop.setProperty("java.lang.ArithmeticException", "error"); exceptionResolver.setExceptionMappings(prop); //设置请求域中共享信息的键 exceptionResolver.setExceptionAttribute("exception"); resolvers.add(exceptionResolver); } //配置Thymeleaf视图解析器 //配置生成模板解析器,对应springMVC.xml中的SpringResourceTemplateResolver @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; } //生成模板引擎并为模板引擎注入模板解析器,对应springMVC.xml中的SpringTemplateEngine //需要上面的SpringResourceTemplateResolver作为依赖 @Bean public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver){ SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); return templateEngine; } //生成视图解析器并为解析器注入模板引擎,对应springMVC.xml中的viewResolver //需要上面的SpringTemplateEngine作为依赖 @Bean public ViewResolver viewResolver(SpringTemplateEngine templateEngine){ ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setCharacterEncoding("UTF-8"); viewResolver.setTemplateEngine(templateEngine); return viewResolver; } }