DispatcherServlet 教程示例

翻译自:https://howtodoinjava.com/spring5/webmvc/spring-dispatcherservlet-tutorial/

一、Spring DispatcherServlet 教程示例
在本教程中, 我们将学习 Spring 的DispatcherServlet类, 它的职责以及如何用示例来配置它。

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

web 应用程序可以定义任意数量的DispatcherServlet实例。每个 servlet 都将在其自己的命名空间中运行, 并使用映射、处理程序等加载自己的应用程序上下文。只有ContextLoaderListener加载的根应用程序上下文 (如果有) 将被共享。在大多数情况下, 应用程序只具有上下文根 URL(/)的单个DispatcherServlet , 即所有进入该域的请求都将由它处理。
DispatcherServlet使用 Spring 配置类来发现它需要的委托组件, 如请求映射、视图解析、异常处理等。
三、如何使用 WebApplicationContext
在基于 Spring 的应用程序中, 我们的应用程序对象位于对象容器中。此容器在对象之间创建对象和关联, 并管理它们的完整生命周期。这些容器对象称为 spring 管理的 bean (或简单的 bean), 并且容器被称为应用程序上下文(通过类ApplicationContext) 在 spring 世界中。
WebApplicationContext是一个普通ApplicationContext的延伸。它是网络感知ApplicationContext , 它具有 Servlet 上下文信息。加载DispatcherServlet时, 它会查找WebApplicationContext的 bean 配置文件并对其进行初始化。
通过访问 Servlet 上下文, 任何实现ServletConextAware接口的 spring bean 都可以访问ServletContext实例并使用它进行许多操作。例如, 它可以获取上下文初始化参数, 获取上下文根信息, 并在 web 应用程序文件夹中获取资源位置
基于 XML 的 DispatcherServlet 配置
我们来看看一个典型的DispatcherServlet声明和初始化的样子。
web. xml
 

<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 的定义。例如
applicationContext.xml
 

<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>

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

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 的初始化

public class ApplicationInitializer implements WebApplicationInitializer
{
    @Override
    public void onStartup(ServletContext container)
    {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);
 
        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));
 
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(DispatcherConfig.class);
 
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher",
                        new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}


在上面的代码中, AppConfig和DispatcherConfig类定义了将在 web 应用程序上下文中使用的 spring 托管 bean。

AbstractDispatcherServletInitializer 示例
这是在 servlet 上下文中注册DispatcherServlet的WebApplicationInitializer实现的基类。
ApplicationInitializer. java

public class ApplicationInitializer extends AbstractDispatcherServletInitializer {
 
    @Override
    protected WebApplicationContext createRootApplicationContext() {
            return null;
    }
 
    @Override
    protected WebApplicationContext createServletApplicationContext() {
            XmlWebApplicationContext cxt = new XmlWebApplicationContext();
            cxt.setConfigLocation("/WEB-INF/dispatcher-servlet-context.xml");
            return cxt;
    }
 
    @Override
    protected String[] getServletMappings() {
            return new String[] { "/" };
    }
 
    //Register filters
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
    }
}


请注意, 如果需要自定义DispatcherServlet, 可以重写createDispatcherServlet()方法。
AbstractAnnotationConfigDispatcherServletInitializer 示例
这个类扩展了AbstractDispatcherServletInitializer , 并做了一些隐含的事情, 否则你可以做自己。一个额外的优点是您现在可以使用 Spring 提供的方便类, 而不是手动配置DispatcherServlet和/或ContextLoaderListener.
它是使用基于 Java 的 Spring 配置的应用程序的首选方法。它使您可以启动 servlet 应用程序上下文和根应用程序上下文。
AppInitializer. java

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 
   @Override
   protected Class<?>[] getRootConfigClasses() {
      return new Class[] { RootConfig.class };
   }
 
   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebMvcConfig.class };
   }
 
   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }
}


 AbstractAnnotationConfigDispatcherServletInitializer会同时创建DispatcherServlet和ContextLoaderListener。

GetServlet-ConfigClasses()方法返回的带有@Configuration注解的类将会用来定义DispatcherServlet应用上下文中的bean。 getRootConfigClasses()方法返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean。

Upon receiving a web request, DispatcherServlet performs a set of operations for request processing. It used a set of supporting beans for this. This table lists these default configured beans and their responsibilities –

Bean Responsibilities
HandlerMapping Maps incoming web requests to handlers and pre- and post-processors
HandlerAdapter Invokes the handler which resolves arguments and dependencies, such as annotated arguments for URL-mapped controller method endpoints
HandlerExceptionResolver Allows programmatic handling of exceptions and maps exceptions to views
ViewResolver Resolves logical view names to view instances
LocaleResolver Resolves the client’s locale in order to enable internationalization
LocaleContextResolver A richer extension of LocaleResolver, with timezone information
ThemeResolver Resolves themes configured in your app for enhanced user experience
MultipartResolver Handles multipart file uploads as part of HTTP requests
FlashMapManager Manages FlashMap instances that store temporary Flash attributes between requests redirected from one another

DispatcherServlet 演示
为了演示DispatcherServlet的使用, 我编写了一个非常最低的应用程序, 它只配置调度程序 servlet 并重写视图解析器 bean。
项目结构

Spring5 MVC 项目结构
AppInitializer. java

package com.howtodoinjava.demo.spring.config;
 
public class AppInitializer 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. java

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.howtodoinjava.demo.spring"})
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;
   }
}

HomeController.java

@Controller
public class HomeController
{
    @GetMapping("/")
    public String homeInit(Locale locale, Model model) {
        return "home";
    }
}


home. jsp
 

<html>
<head>
    <title>Spring 5 Web MVC Example</title>
</head>
<body>
    <h1>HowToDoInJava.com</h1>
    <h2>Spring 5 Web MVC DispatcherServlet Example</h2>
</body>
</html>

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.howtodoinjava.spring5.mvc</groupId>
    <artifactId>spring5-webmvc-demo</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring5-webmvc-demo Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <spring.version>5.0.0.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>
                <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>

Run the application

To run the application execute maven goal : tomcat7:run. Now open http://localhost:8080 in browser.

猜你喜欢

转载自blog.csdn.net/Andy2019/article/details/81175109