目录
5.如何注册其他的Servlet,Filter,Listener.?
1.基于java配置的SpringMVC搭建
传统的web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>springMvc</display-name>
<description>springMvc0.0.1</description>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springMVC需要加载的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- 匹配所有请求,此处也可以配置成 *.do 形式 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置thymeleaf -->
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
传统的SpringMVC的xml启动配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
<!-- 扫描web相关的bean -->
<context:component-scan base-package="com.wx.controller"/>
<!-- 开启SpringMVC注解模式 -->
<mvc:annotation-driven/>
<!-- 静态资源默认servlet配置 -->
<mvc:default-servlet-handler/>
<!--自动任务扫描配置-->
<task:annotation-driven/>
<context:component-scan base-package="com.wx.component"/>
<mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>
<!-- 模板解析器 -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="cacheable" value="false"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
<!--扫描包下所有的被标注的类-->
<context:component-scan base-package="com.wx.domain"/>
<!--配置验证器-->
<bean id="myvalidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
<!--绑定验证器-->
<mvc:annotation-driven validator="myvalidator"/>
<!-- 配置拦截器链 -->
<!--<mvc:interceptors>
<!– 配置第1个拦截器 –>
<mvc:interceptor>
<!– 指定拦截路径,不在拦截路径之内的将不予处理,即拦截器根本就不运行 –>
<mvc:mapping path="/index"/>
<mvc:mapping path="/user/password.do"/>
<!– 指定拦截器类 –>
<bean class="com.wx.Interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>-->
<!-- 自定义的实现类 -->
<bean id="exceptionHandler" class="com.wx.error.CustomExceptionHandler"/>
<!-- 默认的实现类注入 -->
<!-- 配置文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 指定默认的编码格式 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 指定允许上传的文件大小,单位Byte -->
<property name="maxUploadSize" value="5120000000000"/>
</bean>
<!-- 国际化 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="i18n.message"></property>
</bean>
<!-- 国际化操作拦截器如果采用基于(session/cookie)则必须配置 -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
<!-- 配置LocalResolver用来获取本地化语言 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
<!-- 配置LocaleChanceInterceptor拦截器 -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
</beans>
2.SpringMVC是如何启动的?
请求第一站DispatcherServlet(前端控制器),配置DispatcherServlet可以使用web.xml,还可以使用通过继承AbstractAnnotationConfigDispatcherServletInitializer来配置DispatcherServlet,以替代使用web.xml配置DispatcherServlet。
为什么DispatcherServlet启动的时候就会找到AbstractAnnotationConfigDispatcherServletInitializer的扩展呢?在Servlet3.0的容器环境中,容器会在类路径中查找实现ServletContainerInitializer接口的类,如果能发现的话就用它来配置Servlet容器,换句话说我们可以在web容器启动时为提供给第三方组件机会做一些初始化的工作。
Spring的web框架中已经有了ServletContainerInitializer对应的实现类SpringServletContainerInitializer:
SpringServletContainerInitializer反过来又会去找WebApplicationInitializer接口的实现类,即AbstractAnnotationConfigDispatcherServletInitializer,然后就会将初始化的交给他。
AbstractAnnotationConfigDispatcherServletInitializer中做了什么?
3.SpringMVC启动的时候会创建两个两个应用上下文:
- DispatcherServlet启动的时候会创建应用的上下文,它的配置就是在我们自定义的WebConfig中,DispatcherServlet加载的时候会包含Web组件的bean,如控制器,视图解析器,以及映射处理器,
- 而另外一个应用上下文由ContextLoaderListener创建,它的作用是加载应用中的其他bean,这些通常是驱动应用后端的中间层或者数据层组件。
具体两个上下文创建的时候会去加载哪些bean,当然是让用户自己来决定:
getServletConfigClasses()
:定义DispatcherServlet
应用上下文中的 beansgetRootConfigClasses()
:定义拦截器ContextLoaderListener
应用上下文中的 beans
这种配置Servlet的方式只有Servlet3.0的服务器才能使用,如Tomcat7.0及以上。
下面配置SpringMVC,启动DispatcherServlet的方式有多种,那么启动SpringMVC的方式自然也有多种,我们还是使用java配置来实现,这个其实是延续上面DispatcherServlet配置的内容。
启动SpringMVC主要就是一个注解@EnableWebMvc ,启用注解驱动的Spring MVC,使@RequestParam、@RequestMapping等注解可以被识别并且这个类想要称为SpringMVC的启动类就必须要继承WebMvcConfigurationSupport,在SpringMVC的启动类里面需要配置视图解析器和对静态资源的处理:
package com.wx.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
/**
* User: Mr.Wang
* Date: 2020/2/9
*/
@Configuration
@EnableWebMvc// 相当于<mvc:annotation-driver/>,启用注解驱动的Spring MVC,使@RequestParam、@RequestMapping等注解可以被识别
@ComponentScan("com.wx")
public class WebConfig extends WebMvcConfigurationSupport {
/**
* 这里根据不同的前端配置不同的模板引擎
*
* @return
*/
//1.配置模板解析器,ServletContextTemplateResolver被替换成SpringResourceTemplateResolver
@Bean
public SpringResourceTemplateResolver templateResolver(){
SpringResourceTemplateResolver springResourceTemplateResolver = new SpringResourceTemplateResolver();
springResourceTemplateResolver.setPrefix("/WEB-INF/templates/");
springResourceTemplateResolver.setSuffix(".html");
springResourceTemplateResolver.setTemplateMode("HTML5");
springResourceTemplateResolver.setCacheable(false);
springResourceTemplateResolver.setCharacterEncoding("UTF-8");
return springResourceTemplateResolver;
// 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");
// // 设置模板模式,也可用字符串"HTML"代替,此处不建议使用HTML5,原因看下图源码
// templateResolver.setTemplateMode(TemplateMode.HTML);
// return templateResolver;
}
//2.配置Spring的模板引擎
@Bean
public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//3.配置视图解析器
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver templateResolver = new ThymeleafViewResolver();
templateResolver.setTemplateEngine(templateEngine);
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
/**
* 配置静态资源的处理
*
* @param configurer
*/
@Override
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
//对静态资源的请求转发到Servelt容器的默认Servlet中,而不是使用前端控制器来吃力这类请求
configurer.enable();
}
}
ServletConfig已经配置好了,下面我们配置RootConfig,基于web的开发,相关的配置都通过DispatcherServlet配置好了,RootConfig配置就很简单了。
package com.wx.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* User: Mr.Wang
* Date: 2020/3/7
* FilterType.ANNOTATION 按照注解的方式进行扫描.后面classes属性,为注解的类型
*/
@Configuration
@ComponentScan(basePackages = {"com.wx"}, excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)
})
public class RootConfig {
}
测试:
package com.wx.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* User: Mr.Wang
* Date: 2020/3/7
*/
@Controller
public class IndexController {
@RequestMapping("/v1/home")
public String home() {
return "index";
}
}
SpringMVC的java配置:https://blog.csdn.net/z28126308/article/details/54429853
Spring自带的视图解析器:https://www.cnblogs.com/lyj-gyq/p/8963885.html
4.自定义DispatcherServlet配置
AbstractAnnotationConfigDispatcherServletInitializer将DispatcherServlet注册到Servlet容器中之后,就是掉用customizeRegistration()方法。
注册DispatcherServlet:
通过重载customizeRegistration()我们可以对DispatcherServlet进行额外的配置。
5.如何注册其他的Servlet,Filter,Listener.?
第一种方法式是通过实现WebApplicationInitializer接口。如果是Filter的化还可以重载AbstractAnnotationConfigDispatcherServletInitializer的getServletFilter方法,这种方式就不需要指明Filter的路径,他会全部映射到DispatcherServlet上。