SpringMVC与Servlet 3.0结合

凯哥Java 2020-02-16

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本身来处理静态资源请求。
    }

}
 

相关推荐