leftso 1526 0 2018-03-24 09:45:08

文章位置:左搜> 编程技术> 正文

引言

  在本教程中,我们将学习Spring DispatcherServlet类,其职责以及如何使用示例进行配置。spring mvc 5.0基于Java配置

一.DispatcherServlet是什么


    DispatcherServlet 充当基于Spring的Web应用程序的前端控制器。 它提供了一个请求处理机制,其中实际工作由可配置的委托组件执行。 它从javax.servlet.http.HttpServlet继承,通常在web.xml文件中配置。

    Web应用程序可以定义任意数量的DispatcherServlet 实例。 每个servlet将在其自己的名称空间中运行,使用映射,处理程序等加载它自己的应用程序上下文。只有由ContextLoaderListener加载的根应用程序上下文(如果有)将被共享。 在大多数情况下,应用程序只有一个具有上下文根URL(/)的DispatcherServlet ,也就是说,到达该域的所有请求都将由它处理。

    DispatcherServlet 使用Spring配置类来发现它需要的委托组件,用于请求映射,视图解析,异常处理等。

二.DispatcherServlet它如何使用WebApplicationContext

    在基于Spring的应用程序中,我们的应用程序对象位于一个对象容器中。 该容器在对象之间创建对象和关联,并管理其完整的生命周期。 这些容器对象被称为Spring管理的bean(或者简单的bean),在Spring世界中容器被称为应用程序上下文(通过类ApplicationContext)。

    WebApplicationContext是一个普通的ApplicationContext的扩展。 它是Web感知的ApplicationContext,即它具有Servlet上下文信息。 当DispatcherServlet被加载时,它查找WebApplicationContext的bean配置文件并初始化它。

    通过访问Servlet上下文,任何实现了ServletConextAware接口的spring bean都可以访问ServletContext实例,并且可以做很多事情。 例如,它可以获取上下文初始化参数,获取上下文根信息并获取Web应用程序文件夹中的资源位置。

三.基于XML配置的DispatcherServlet(作为参考理解主讲基于Java配置)

我们来看看典型的DispatcherServlet声明和初始化是怎样的。
<web-app>
 
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
 
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dispatcher-servlet-context.xml</param-value>
  </context-param>
 
  <servlet>
    <servlet-name>dispatcher-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>dispatcher-servlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
 
</web-app>
在上面的代码中,dispatcher-servlet-context.xml文件将包含所有可用于DispatcherServlet的bean定义和关联。 这些bean定义将覆盖在全局范围内使用相同名称定义的任何bean的定义。 例如:
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
 
</beans>

四.基于JAVA代码配置的DispatcherServlet 

从Servlet 3.0开始,除了web.xml文件中的声明式配置,DispatcherServlet可以通过实现或扩展Spring提供的这三个支持类来编程配置 
  • WebAppInitializer接口
  • AbstractDispatcherServletInitializer抽象类
  • AbstractAnnotationConfigDispatcherServletInitializer抽象类
在下面的类中,WebApplicationInitializer确保ApplicationSerializer类被SpringServletContainerInitializer(它本身自动引导)检测到并用来初始化任何Servlet 3容器。

引入spring mvc 5.0需要的相关依赖,pom.xml:
<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.leftso.project.demo</groupId>
	<artifactId>demo-spring5-springmvc5</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	 <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <spring.version>5.0.1.RELEASE</spring.version>
        <jstl.version>1.2.1</jstl.version>
        <tld.version>1.1.2</tld.version>
        <servlets.version>3.1.0</servlets.version>
        <jsp.version>2.3.1</jsp.version>
    </properties>
	<dependencies>
        <!-- Spring MVC Dependency -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
         
        <!-- JSTL Dependency -->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>javax.servlet.jsp.jstl-api</artifactId>
            <version>${jstl.version}</version>
        </dependency>
         
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>${tld.version}</version>
        </dependency>
 
        <!-- Servlet Dependency -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlets.version}</version>
            <scope>provided</scope>
        </dependency>
 
        <!-- JSP Dependency -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>${jsp.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
	
	<build>
		<sourceDirectory>src/main/java</sourceDirectory>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			 <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <path>/</path>
                </configuration>
            </plugin>
		</plugins>
	</build>
</project>


通过Java的方式可以将上面的web.xml写一个配置类:
public class ApplicationInitializer implements WebApplicationInitializer
{
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException
    {
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("/WEB-INF/dispatcher-servlet-context.xml");
 
        ServletRegistration.Dynamic registration = servletContext
                    .addServlet("rootDispatcher", new DispatcherServlet(appContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}
基于Java 配置的完整配置
例子一:
package com.leftso.project.demo.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class ApplicationInitializer implements WebApplicationInitializer {

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {

		// 创建 Spring ROOT context
		AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
		rootContext.register(AppConfig.class);

		// 管理ROOT context生命周期
		servletContext.addListener(new ContextLoaderListener(rootContext));

		// 创建spring的dispatcher ,servlet's Spring application context
		AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
		dispatcherContext.register(DispatcherConfig.class);

		ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher",
				new DispatcherServlet(dispatcherContext));
		dispatcher.setLoadOnStartup(1);
		dispatcher.addMapping("/");
	}

}
在上面的代码中,AppConfig 和DispatcherConfig 类定义了将在Web应用程序上下文中的spring管理的bean。
AppConfig:
package com.leftso.project.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.leftso.project.demo.TestService;

@Configuration
@ComponentScan(basePackages = { "com.leftso" })
public class AppConfig {
	// 该类主要是spring 父级容器配置,里面可以定义很多的bean就像在spring-context.xml中一样
	// 例如:
	@Bean
	public TestService testService() {
		return new TestService();
	}
}
DispatcherConfig:
package com.leftso.project.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
public class DispatcherConfig extends WebMvcConfigurationSupport {
	// 覆盖父类的配置进行spring mvc的其他详细配置,配置内容可参考xml的spring-mvc
	/**
	 * 
	 * <pre>
	 * [Function]:
	 * JSP 视图解析器
	 * [Description]:
	 * JSP 视图解析器
	 * </pre>
	 * 
	 * @return JSP 视图解析器
	 */
	@Bean
	public ViewResolver jspViewResolver() {
		InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
		internalResourceViewResolver.setViewClass(JstlView.class);
		internalResourceViewResolver.setSuffix(".jsp");
		internalResourceViewResolver.setPrefix("/WEB-INF/views/");
		internalResourceViewResolver.setOrder(4);
		return internalResourceViewResolver;
	}

	/**
	 * 资源文件处理器
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}
}

例子二:
基于Java配置的Spring MVC 5.0的配置,spring mvc 5.0为我们提供了一个封装的抽象类,我们实现这个类并指定相关的配置Java就可以了非常方便:

package com.leftso.project.demo.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * Spring MVC 5启动配置
 * 
 * @author xqlee
 *
 */
public class SpringMVC5AnnotationConfigDispatcherServletInitializer
		extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class<?>[] {};
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[] { WebMvcConfig.class };
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}

}

WebMvcConfig:
 

package com.leftso.project.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.leftso.project.demo" })
public class WebMvcConfig implements WebMvcConfigurer {
	@Bean
	public InternalResourceViewResolver resolver() {
		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
		resolver.setViewClass(JstlView.class);
		resolver.setPrefix("/WEB-INF/views/");
		resolver.setSuffix(".jsp");
		return resolver;
	}
}

这比起第一种方式少些几句代码。


五.编写一个测试spring mvc 5.0的controller

package com.leftso.project.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

	@GetMapping("/sayHello.do")
	public Object sayHello(String name) {
		return "Hello," + name;
	}

}
将项目添加到tomcat中,启动tomcat,并在浏览器中访问controller的地址:
spring mvc 5.0
从上图可以看到我们的spring mvc5.0项目已经成功启动.后续将讲解整合其他配置
 

评论区域

暂无评论,快来抢首发吧!!!