SpringMVC与Servlet 3.0结合
Web容器
web容器(web服务器)主要有:Apache、IIS、Tomcat、Jetty、JBoss、webLogic等,而Tomcat、Jetty、JBoss、webLogic同时也是servlet容器,或者说他们还包含了servlet容器。没有servlet容器,你也可以用web容器直接访问静态页面,比如安装一个apache等,但是如果要显示jsp/servlet,你就要安装一个servlet容器了,但是光有servlet容器是不够的,因为它要被解析成html输出,所以你仍需要一个web容器。大多数servlet容器同时提供了web容器的功能,也就是说大多servelt容器可以独立运行你的web应用。
web容器是管理servlet(通过servlet容器),以及监听器(Listener)和过滤器(Filter)的。这些都是在web容器的掌控范围里。但他们不在spring和springmvc的掌控范围里。因此,我们无法在这些类中直接使用Spring注解的方式来注入我们需要的对象,是无效的,web容器是无法识别的。
引用自下文:https://www.cnblogs.com/jieerma666/p/10805966.html
Tomcat 7以上的版本支持Servlet3.0。在Servlet 3.0环境中,当容器启动时,容器会在类路径中查找ServletContainerInitializer接口的实现类,如果发现这样的类就会用这个类来配置Servlet容器(Tomcat,Jetty)。
javax.servlet.ServletContainerInitializer
在spring中有存在一个SpringServletContainerInitializer类实现了ServletContainerInitializer接口,SpringServletContainerInitializer类在onStartup方法中又去查找
WebApplicationInitializer接口的实现类,在spring中有一个WebApplicationInitializer的实现类AbstractAnnotationConfigDispatcherServletInitializer。因此只要继承AbstractAnnotationConfigDispatcherServletInitializer类就可以配置DispatcherServlet与Spring的ApplicationContext(Spring的核心接口,是BeanFactory接口的子接口)。
org.springframework.web.SpringServletContainerInitializer org.springframework.web.WebApplicationInitializer org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
下面就是扩展AbstractAnnotationConfigDispatcherServletInitializer的类
package spitter.config; import javax.servlet.Filter; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import spitter.web.MyFilter; public class SpitterWebApplication extends AbstractAnnotationConfigDispatcherServletInitializer{ /** * 指定主配置类 */ @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[]{RootConfig.class}; } /** * 指定springMVC配置类 */ @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[]{WebConfig.class}; } /** * 将一个或者多个路径映射到DispatcherServlet上 */ @Override protected String[] getServletMappings() { return new String[] {"/"}; } /** * 当AbstractAnnotationConfigDispatcherServletInitializer 将DispatcherServlet注册到Servlet容器之后, * 就会调用customizeRegistration方法,并把Servlet注册之后得到的Registration.Dynamic传递过来,通过重写 * customizeRegistration方法,我们可以对DispatcherServlet进行额外的配置 */ @Override protected void customizeRegistration(Dynamic registration) { System.out.println("dispatcherServlet已经注册完成"); registration.setMultipartConfig(new MultipartConfigElement("/tmp/spitter/uploads")); } @Override protected Filter[] getServletFilters() { // TODO Auto-generated method stub return new Filter[] {new MyFilter()}; } }
在springMVC应用程序中一般有两个上下文应用。
一个是Spring的应用上下文,是由ContextLoaderListener监听器进行创建,这个监听器是一个ServletContextListener的子类,也就是ServletContext监听器。这个应用上下文加载应用中的业务层与数据访问的的一些bean.
另一个是SpringMVC的应用上下文,是由DispatcherServlet启动时创建的。这个应用上下文加载一个Web组件的bean,例如控制器,视图解析器,以及处理器映射器。
以前连个应用上下文在创建时都需要都xml配置文件,两个上下文的配置文件的位置在web.xml中进行配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <!-- 在ServletContextListener中初始化spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 在DispatcherServlet中初始化springMVC容器 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 设置过滤器,设置字符编码 --> <!-- 字符编码过滤器 --> <filter> <filter-name>characterEncodingFilter</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> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResposeEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置cxf的核心控制器 --> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <load-on-startup>2</load-on-startup> </servlet> <!-- 所有来自/webservice/*的请求交给cxf处理 --> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping> </web-app>
和Servlet 3.0结合之后,就可以采用两个java配置类代替xml配置文件
package spitter.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @ComponentScan(basePackages = {"spitter"},excludeFilters (type=FilterType.ANNOTATION,value=EnableWebMvc.class)) public class RootConfig { }
package spitter.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; 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.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration//声明为配置类 @EnableWebMvc//启动SpringMVC组件。如果在xml配置,也可以采用<mvc:annotation-driven>标签启动 @ComponentScan("spitter.web")//启动扫描组件 public class WebConfig extends WebMvcConfigurationSupport { //配置视图解析器 @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver=new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } //配置静态资源处理 @Override protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable();//通过调用enable()方法,我们要求DispatcherServlet对静态资源的请求转发到 //Servlet容器中默认的Servlet上,而不是使用DispatcherServlet本身来处理静态资源请求。 } }