GVKun编程网logo

Null ModelAndView返回给DispatcherServlet(contentdocument返回null)

9

对于想了解NullModelAndView返回给DispatcherServlet的读者,本文将是一篇不可错过的文章,我们将详细介绍contentdocument返回null,并且为您提供关于----

对于想了解Null ModelAndView返回给DispatcherServlet的读者,本文将是一篇不可错过的文章,我们将详细介绍contentdocument返回null,并且为您提供关于------>Servlet.service() for servlet [dispatcherServlet] in context with path [] threw excepti...、DispatcherServlet、DispatcherServlet 详解、dispatcherServlet-servlet.xml (SSM maven 项目)的有价值信息。

本文目录一览:

Null ModelAndView返回给DispatcherServlet(contentdocument返回null)

Null ModelAndView返回给DispatcherServlet(contentdocument返回null)

我正在尝试使用Spring,Hibernate和Apache Tiles运行我的Web应用程序。似乎代码没有错误,但是我只得到404页。

/var/log/tomcat7/catalina.out:

DEBUG: org.springframework.web.servlet.DispatcherServlet - Servlet ''dispatcher'' configured successfullyDEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name ''dispatcher'' processing GET request for [/example/index.html]DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /index.htmlDEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/index.html]DEBUG: org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Matching patterns for request [/index.html] are [/**]DEBUG: org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - URI Template variables for request [/index.html] are {}DEBUG: org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapping [/index.html] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler@32645ccb] and 1 interceptorDEBUG: org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/example/index.html] is: -1DEBUG: org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name ''dispatcher'': assuming HandlerAdapter completed request handlingDEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request

Servlet:

<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:/META-INF/spring/dispatcher-servlet.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>

上下文:

<mvc:annotation-driven /><tx:annotation-driven /><bean id="viewResolver">    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" /></bean><bean id="tilesConfigurer">    <property name="definitions">        <value>            /WEB-INF/**/tiles.xml        </value>    </property></bean><context:component-scan base-package="com.example.controller" /><resources mapping="/resources/**" location="/resources/" /><default-servlet-handler /><context:property-placeholder location="classpath:jdbc.properties" /><bean id="dataSource"destroy-method="close">    <property name="driverClassName" value="${jdbc.driverClassName}" />    <property name="url" value="${jdbc.url}" />    <property name="username" value="${jdbc.username}" />    <property name="password" value="${jdbc.password}" /></bean><bean id="sessionFactory">    <property name="dataSource" ref="dataSource" />    <property name="packagesToScan" value="com.example.model" />    <property name="hibernateProperties">        <props>            <prop key="hibernate.dialect">${hibernate.dialect}</prop>            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>            <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>        </props>    </property></bean><bean id="transactionManager">    <property name="sessionFactory" ref="sessionFactory" /></bean>

Maven依赖项:

<properties>    <java.version>1.6</java.version>    <spring.version>3.1.1.RELEASE</spring.version>    <slf4j.version>1.6.4</slf4j.version></properties><dependencies>    <dependency>        <groupId>cglib</groupId>        <artifactId>cglib</artifactId>        <version>2.2.2</version>    </dependency>    <!-- Spring -->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-context</artifactId>        <version>${spring.version}</version>        <exclusions>            <!-- Exclude Commons Logging in favor of SLF4j -->            <exclusion>                <groupId>commons-logging</groupId>                <artifactId>commons-logging</artifactId>             </exclusion>        </exclusions>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-orm</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-tx</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>        <version>${spring.version}</version>    </dependency>    <!-- Logging -->    <dependency>        <groupId>org.slf4j</groupId>        <artifactId>slf4j-api</artifactId>        <version>${slf4j.version}</version>    </dependency>    <dependency>        <groupId>org.slf4j</groupId>        <artifactId>jcl-over-slf4j</artifactId>        <version>${slf4j.version}</version>    </dependency>    <dependency>        <groupId>org.slf4j</groupId>        <artifactId>slf4j-log4j12</artifactId>        <version>${slf4j.version}</version>        <scope>runtime</scope>    </dependency>    <dependency>        <groupId>log4j</groupId>        <artifactId>log4j</artifactId>        <version>1.2.17</version>        <scope>runtime</scope>    </dependency>    <!-- Hibernate -->    <dependency>        <groupId>org.hibernate</groupId>        <artifactId>hibernate-core</artifactId>        <version>4.1.1.Final</version>    </dependency>    <dependency>        <groupId>postgresql</groupId>        <artifactId>postgresql</artifactId>        <version>9.1-901-1.jdbc4</version>    </dependency>    <!-- Servlet -->    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>servlet-api</artifactId>        <version>2.5</version>        <scope>provided</scope>    </dependency>    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>jstl</artifactId>        <version>1.2</version>    </dependency>    <!-- Apache Tiles -->    <dependency>        <groupId>org.apache.tiles</groupId>        <artifactId>tiles-jsp</artifactId>        <version>2.2.2</version>        <exclusions>            <!-- Exclude Commons Logging in favor of SLF4j -->            <exclusion>                <groupId>commons-logging</groupId>                <artifactId>commons-logging-api</artifactId>             </exclusion>        </exclusions>    </dependency>    <!-- JSR 303 with Hibernate Validator -->    <dependency>        <groupId>javax.validation</groupId>        <artifactId>validation-api</artifactId>        <version>1.0.0.GA</version>    </dependency>    <dependency>        <groupId>org.hibernate</groupId>        <artifactId>hibernate-validator</artifactId>        <version>4.1.0.Final</version>    </dependency></dependencies>

在添加所有hibernate内容之前,我尝试了该Web应用程序,它的运行效果非常好。但是什么是没有数据库的Web应用程序?

我已经花了几个小时才发现问题…

更新

控制器:

package com.example.controller;import java.util.Map;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/")public class BlogController {    @RequestMapping("/index.html")    public String posts(Map<String, Object> map) {        return "posts";    }}

答案1

小编典典

我解决了

有两个上下文:root(应用程序范围)和servlet上下文(我定义viewResolvertilesConfigurertx:annotation-driven以及mvc:annotation-drivenroot上下文。

将其移至Servlet上下文即可解决此问题。

已更新 我感动viewResolvertilesConfigurertx:annotation-drivenmvc:annotation-driven从定义applicationContext.xmlcontextConfigLocationdispatcher-servlet.xml

------>Servlet.service() for servlet [dispatcherServlet] in context with path [] threw excepti...

------>Servlet.service() for servlet [dispatcherServlet] in context with path [] threw excepti...


java.lang.NullPointerException: null
    at com.book.app.web.UserController.findPageWith(UserController.java:50) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) ~[shiro-core-1.2.3.jar:1.2.3]
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) ~[shiro-core-1.2.3.jar:1.2.3]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383) ~[shiro-core-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) ~[shiro-web-1.2.3.jar:1.2.3]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123) ~[druid-1.1.10.jar:1.1.10]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1457) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
总结:持久层,业务层,表现成,都写的正确;

原来错误是页面相关属性的单词写错了·····················晕

DispatcherServlet

DispatcherServlet

DispatcherServlet 是实现 Servlet 接口的实现类。

Servlet 生命周期由 serlvet 容器来控制。分为 3 个阶段:初始化,运行和销毁。

(1)初始化阶段。

     Servlet 容器加载 servlet 类,把 servlet 类的.class 文件中的数据读到内存中。

     Servlet 容器创建一个 ServletConfig 对象。ServletConfig 对象包含了 servlet 的初始化配置信息。

    Servlet 容器创建一个 servlet 对象。

    Servlet 容器调用 servlet 对象的 init 进行初始化。

(2)运行阶段。

当 Servlet 容器接收到一个请求,创建 servletRequest 和 servletResponse 对象,然后调用 servlet 方法。Servlet 通过 servletRequest 对象获取请求信息。处理请求。再通过 servletResponse 对象请求响应结果。然后销毁 servletRequest 和 servletResponse 对象.

(3) 销毁阶段。

当 web 应用终止,servlet 容器会先调用 servlet 对象的 destory 方法,然后再销毁 servlet 对象,同时也会销毁 ServletConfig 对象。

DispatcherServlet 的逻辑处理

doService 方法调用 doDispatch 方法

doDispatch 函数

1.checkMultipart

如果请求是 MultipartContent,则转换为 MultipartHttpServletRequest 类型的请求。

2.getHandler(HandlerMapping)

  根据 request 信息寻找对应的 Handler

  (1) lookupHandler: 根据路径通过直接匹配或通配符匹配寻找 Handler. 然后在 buildPathExposingHandler 函数将 Handler 封装成 HandlerExecutionChain 类型。

  (2)getHandlerExecutionChain 函数将配置中的对应拦截器加入到执行链中,保证这些拦截器可以有效地作用于目标对象。

3.getHandlerAdapter:根据当前的 Handler 寻找对应的 HandlerAdapter.

4.processHandlerException: 异常师徒的处理。

5.Render: 根据视图跳转页面。

 

DispatcherServlet 详解

DispatcherServlet 详解

DispatcherServlet 作用

DispatcherServlet 是前端控制器设计模式的实现,提供 Spring Web MVC 的集中访问点,而且负责职责的分派,而且与 Spring IoC 容器无缝集成,从而可以获得 Spring 的所有好处。 具体请参考第二章的图 2-1。

DispatcherServlet 主要用作职责调度工作,本身主要用于控制流程,主要职责如下:

1、文件上传解析,如果请求类型是 multipart 将通过 MultipartResolver 进行文件上传解析;

2、通过 HandlerMapping,将请求映射到处理器(返回一个 HandlerExecutionChain,它包括一个处理器、多个 HandlerInterceptor 拦截器);

3、通过 HandlerAdapter 支持多种类型的处理器 (HandlerExecutionChain 中的处理器);

4、通过 ViewResolver 解析逻辑视图名到具体视图实现;

5、本地化解析;

6、渲染具体的视图等;

7、如果执行过程中遇到异常将交给 HandlerExceptionResolver 来解析。

从以上我们可以看出 DispatcherServlet 主要负责流程的控制(而且在流程中的每个关键点都是很容易扩展的)。

DispatcherServlet 在 web.xml 中的配置

<servlet>
        <servlet-name>chapter2</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>chapter2</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

load-on-startup表示启动容器时初始化该 Servlet;

url-pattern表示哪些请求交给 Spring Web MVC 处理, “/” 是用来定义默认 servlet 映射的。也可以如 “*.html” 表示拦截所有以 html 为扩展名的请求。

该 DispatcherServlet 默认使用 WebApplicationContext 作为上下文,Spring 默认配置文件为 “/WEB-INF/[servlet 名字]-servlet.xml”。

DispatcherServlet 也可以配置自己的初始化参数,覆盖默认配置:

参数

描述

contextClass

实现 WebApplicationContext 接口的类,当前的 servlet 用它来创建上下文。如果这个参数没有指定, 默认使用 XmlWebApplicationContext。

contextConfigLocation

传给上下文实例(由 contextClass 指定)的字符串,用来指定上下文的位置。这个字符串可以被分成多个字符串(使用逗号作为分隔符) 来支持多个上下文(在多上下文的情况下,如果同一个 bean 被定义两次,后面一个优先)。

namespace

WebApplicationContext 命名空间。默认值是 [server-name]-servlet。

因此我们可以通过添加初始化参数

<servlet>
        <servlet-name>chapter2</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet-config.xml</param-value>
        </init-param>
    </servlet>

如果使用如上配置,Spring Web MVC 框架将加载 “classpath:spring-servlet-config.xml” 来进行初始化上下文而不是 “/WEB-INF/[servlet 名字]-servlet.xml”。

上下文关系

集成 Web 环境的通用配置:

<context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
          classpath:spring-common-config.xml,
          classpath:spring-budget-config.xml
      </param-value>
</context-param>
<listener>  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

如上配置是 Spring 集成 Web 环境的通用配置;一般用于加载除 Web 层的 Bean(如 DAO、Service 等),以便于与其他任何 Web 框架集成。

contextConfigLocation:表示用于加载 Bean 的配置文件;

contextClass:表示用于加载 Bean 的 ApplicationContext 实现类,默认 WebApplicationContext。

ContextLoaderListener 初始化的上下文和 DispatcherServlet 初始化的上下文关系,如图 3-1

图 3-1

创建完毕后会将该上下文放在 ServletContext:

servletContext.setAttribute(

WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,

this.context);

从图中可以看出:

ContextLoaderListener 初始化的上下文加载的 Bean 是对于整个应用程序共享的,不管是使用什么表现层技术,一般如 DAO 层、Service 层 Bean;

DispatcherServlet 初始化的上下文加载的 Bean 是只对 Spring Web MVC 有效的 Bean,如 Controller、HandlerMapping、HandlerAdapter 等等,该初始化上下文应该只加载 Web 相关组件。

DispatcherServlet 初始化顺序

继承体系结构如下所示:

1、HttpServletBean 继承 HttpServlet因此在 Web 容器启动时将调用它的 init 方法,该初始化方法的主要作用

:::将 Servlet 初始化参数(init-param)设置到该组件上(如 contextAttribute、contextClass、namespace、contextConfigLocation),通过 BeanWrapper 简化设值过程,方便后续使用;

:::提供给子类初始化扩展点,initServletBean (),该方法由 FrameworkServlet 覆盖。

 

public abstract class HttpServletBean extends HttpServlet implements EnvironmentAware{
@Override
    public final void init() throws ServletException {
       //省略部分代码
       //1、如下代码的作用是将Servlet初始化参数设置到该组件上
//如contextAttribute、contextClass、namespace、contextConfigLocation;
       try {
           PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
           BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
           ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
           bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
           initBeanWrapper(bw);
           bw.setPropertyValues(pvs, true);
       }
       catch (BeansException ex) {
           //…………省略其他代码
       }
       //2、提供给子类初始化的扩展点,该方法由FrameworkServlet覆盖
       initServletBean();
       if (logger.isDebugEnabled()) {
           logger.debug("Servlet ''" + getServletName() + "'' configured successfully");
       }
    }
    //…………省略其他代码
}

 

 

2、FrameworkServlet 继承 HttpServletBean通过 initServletBean () 进行 Web 上下文初始化,该方法主要覆盖一下两件事情:

    初始化 web 上下文;

    提供给子类初始化扩展点;

public abstract class FrameworkServlet extends HttpServletBean {
@Override
    protected final void initServletBean() throws ServletException {
        //省略部分代码
       try {
             //1、初始化Web上下文
           this.webApplicationContext = initWebApplicationContext();
             //2、提供给子类初始化的扩展点
           initFrameworkServlet();
       }
        //省略部分代码
    }
}

 

protected WebApplicationContext initWebApplicationContext() {
        //ROOT上下文(ContextLoaderListener加载的)
       WebApplicationContext rootContext =
              WebApplicationContextUtils.getWebApplicationContext(getServletContext());
       WebApplicationContext wac = null;
       if (this.webApplicationContext != null) {
           // 1、在创建该Servlet注入的上下文
           wac = this.webApplicationContext;
           if (wac instanceof ConfigurableWebApplicationContext) {
              ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
              if (!cwac.isActive()) {
                  if (cwac.getParent() == null) {
                      cwac.setParent(rootContext);
                  }
                  configureAndRefreshWebApplicationContext(cwac);
              }
           }
       }
       if (wac == null) {
             //2、查找已经绑定的上下文
           wac = findWebApplicationContext();
       }
       if (wac == null) {
            //3、如果没有找到相应的上下文,并指定父亲为ContextLoaderListener
           wac = createWebApplicationContext(rootContext);
       }
       if (!this.refreshEventReceived) {
             //4、刷新上下文(执行一些初始化)
           onRefresh(wac);
       }
       if (this.publishContext) {
           // Publish the context as a servlet context attribute.
           String attrName = getServletContextAttributeName();
           getServletContext().setAttribute(attrName, wac);
           //省略部分代码
       }
       return wac;
    }

从 initWebApplicationContext()方法可以看出,基本上如果 ContextLoaderListener 加载了上下文将作为根上下文(DispatcherServlet 的父容器)。

最后调用了 onRefresh () 方法执行容器的一些初始化,这个方法由子类实现,来进行扩展。

3、DispatcherServlet 继承 FrameworkServlet,并实现了 onRefresh () 方法提供一些前端控制器相关的配置:

public class DispatcherServlet extends FrameworkServlet {
     //实现子类的onRefresh()方法,该方法委托为initStrategies()方法。
    @Override
    protected void onRefresh(ApplicationContext context) {
       initStrategies(context);
    }
 
    //初始化默认的Spring Web MVC框架使用的策略(如HandlerMapping)
    protected void initStrategies(ApplicationContext context) {
       initMultipartResolver(context);
       initLocaleResolver(context);
       initThemeResolver(context);
       initHandlerMappings(context);
       initHandlerAdapters(context);
       initHandlerExceptionResolvers(context);
       initRequestToViewNameTranslator(context);
       initViewResolvers(context);
       initFlashMapManager(context);
    }
}

从如上代码可以看出,DispatcherServlet 启动时会进行我们需要的 Web 层 Bean 的配置,如 HandlerMapping、HandlerAdapter 等,而且如果我们没有配置,还会给我们提供默认的配置。

从如上代码我们可以看出,整个 DispatcherServlet 初始化的过程和做了些什么事情,具体主要做了如下两件事情:

1、初始化 Spring Web MVC 使用的 Web 上下文,并且可能指定父容器为(ContextLoaderListener 加载了根上下文);

2、初始化 DispatcherServlet 使用的策略,如 HandlerMapping、HandlerAdapter 等。

服务器启动时的日志分析(此处加上了 ContextLoaderListener 从而启动 ROOT 上下文容器):

 

 信息: Initializing Spring root WebApplicationContext // ContextLoaderListener 启动 ROOT 上下文

2012-03-12 13:33:55 [main] INFO  org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started

2012-03-12 13:33:55 [main] INFO  org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Mon Mar 12 13:33:55 CST 2012]; root of context hierarchy

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader - Loading bean definitions

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 0 bean definitions from location pattern [/WEB-INF/ContextLoaderListener.xml]

2012-03-12 13:33:55 [main] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Bean factory for Root WebApplicationContext: org.springframework.beans.factory.support.DefaultListableBeanFactory@1c05ffd: defining beans []; root of factory hierarchy

2012-03-12 13:33:55 [main] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Bean factory for Root WebApplicationContext:

2012-03-12 13:33:55 [main] DEBUG org.springframework.web.context.ContextLoader - Published root WebApplicationContext as ServletContext attribute with name [org.springframework.web.context.WebApplicationContext.ROOT] // ROOT 上下文绑定到 ServletContext

2012-03-12 13:33:55 [main] INFO  org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 438 ms  // 到此 ROOT 上下文启动完毕

 

 2012-03-12 13:33:55 [main] DEBUG org.springframework.web.servlet.DispatcherServlet - Initializing servlet ''chapter2''

信息: Initializing Spring FrameworkServlet ''chapter2''  // 开始初始化 FrameworkServlet 对应的 Web 上下文

2012-03-12 13:33:55 [main] INFO  org.springframework.web.servlet.DispatcherServlet - FrameworkServlet ''chapter2'': initialization started

2012-03-12 13:33:55 [main] DEBUG org.springframework.web.servlet.DispatcherServlet - Servlet with name ''chapter2'' will try to create custom WebApplicationContext context of class ''org.springframework.web.context.support.XmlWebApplicationContext'', using parent context [Root WebApplicationContext: startup date [Mon Mar 12 13:33:55 CST 2012]; root of context hierarchy]

// 此处使用 Root WebApplicationContext 作为父容器。

2012-03-12 13:33:55 [main] INFO  org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace ''chapter2-servlet'': startup date [Mon Mar 12 13:33:55 CST 2012]; parent: Root WebApplicationContext

2012-03-12 13:33:55 [main] INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/chapter2-servlet.xml]

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader - Loading bean definitions

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.BeanDefinitionParserDelegate - Neither XML ''id'' nor ''name'' specified - using generated bean name[org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping#0]  // 我们配置的 HandlerMapping

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.BeanDefinitionParserDelegate - Neither XML ''id'' nor ''name'' specified - using generated bean name[org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter#0] // 我们配置的 HandlerAdapter

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.BeanDefinitionParserDelegate - Neither XML ''id'' nor ''name'' specified - using generated bean name [org.springframework.web.servlet.view.InternalResourceViewResolver#0] // 我们配置的 ViewResolver

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.BeanDefinitionParserDelegate - No XML ''id'' specified - using ''/hello'' as bean name and [] as aliases 

// 我们的处理器(HelloWorldController

2012-03-12 13:33:55 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 4 bean definitions from location pattern [/WEB-INF/chapter2-servlet.xml]

2012-03-12 13:33:55 [main] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Bean factory for WebApplicationContext for namespace ''chapter2-servlet'': org.springframework.beans.factory.support.DefaultListableBeanFactory@1372656: defining beans [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping#0,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter#0,org.springframework.web.servlet.view.InternalResourceViewResolver#0,/hello]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@1c05ffd

// 到此容器注册的 Bean 初始化完毕

2012-03-12 13:33:56 [main] DEBUG org.springframework.web.servlet.DispatcherServlet - Unable to locate MultipartResolver with name ''multipartResolver'': no multipart request handling provided

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean ''org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver''

// 默认的 LocaleResolver 注册

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean ''org.springframework.web.servlet.theme.FixedThemeResolver''

// 默认的 ThemeResolver 注册

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean ''org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping#0''

// 发现我们定义的 HandlerMapping 不再使用默认的 HandlerMapping

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean ''org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter#0''

// 发现我们定义的 HandlerAdapter 不再使用默认的 HandlerAdapter

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean ''org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver''

// 异常处理解析器 ExceptionResolver

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean ''org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver''

2012-03-12 13:33:56 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean ''org.springframework.web.servlet.view.InternalResourceViewResolver#0''

2012-03-12 13:33:56 [main] DEBUG org.springframework.web.servlet.DispatcherServlet - Published WebApplicationContext of servlet ''chapter2'' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.chapter2]

// 绑定 FrameworkServlet 初始化的 Web 上下文到 ServletContext

2012-03-12 13:33:56 [main] INFO  org.springframework.web.servlet.DispatcherServlet - FrameworkServlet ''chapter2'': initialization completed in  297 ms

2012-03-12 13:33:56 [main] DEBUG org.springframework.web.servlet.DispatcherServlet - Servlet ''chapter2'' configured successfully

// 到此完整流程结束 

从如上日志我们也可以看出,DispatcherServlet 会进行一些默认的配置。接下来我们看一下默认配置吧。

DispatcherServlet 默认配置

DispatcherServlet 的默认配置在 DispatcherServlet.properties(和 DispatcherServlet 类在一个包下)中,而且是当 Spring 配置文件中没有指定配置时使用的默认策略:

 

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\

    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\

    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\

    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\

    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\

    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

从如上配置可以看出 DispatcherServlet 在启动时会自动注册这些特殊的 Bean,无需我们注册,如果我们注册了,默认的将不会注册。

因此如第二章的 BeanNameUrlHandlerMapping、SimpleControllerHandlerAdapter 是不需要注册的,DispatcherServlet 默认会注册这两个 Bean。

从 DispatcherServlet.properties 可以看出有许多特殊的 Bean,那接下来我们就看看 Spring Web MVC 主要有哪些特殊的 Bean。

DispatcherServlet 中使用的特殊的 Bean

DispatcherServlet 默认使用 WebApplicationContext 作为上下文,因此我们来看一下该上下文中有哪些特殊的 Bean:

1、Controller处理器 / 页面控制器,做的是 MVC 中的 C 的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理;

2、HandlerMapping请求到处理器的映射,如果映射成功返回一个 HandlerExecutionChain 对象(包含一个 Handler 处理器(页面控制器)对象、多个 HandlerInterceptor 拦截器)对象;如 BeanNameUrlHandlerMapping 将 URL 与 Bean 名字映射,映射成功的 Bean 就是此处的处理器;

3、HandlerAdapterHandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;如 SimpleControllerHandlerAdapter 将对实现了 Controller 接口的 Bean 进行适配,并且掉处理器的 handleRequest 方法进行功能处理;

4、ViewResolverViewResolver 将把逻辑视图名解析为具体的 View,通过这种策略模式,很容易更换其他视图技术;如 InternalResourceViewResolver 将逻辑视图名映射为 jsp 视图;

5、LocalResover本地化解析,因为 Spring 支持国际化,因此 LocalResover 解析客户端的 Locale 信息从而方便进行国际化;

6、ThemeResovler主题解析,通过它来实现一个页面多套风格,即常见的类似于软件皮肤效果;

7、MultipartResolver文件上传解析,用于支持文件上传;

8HandlerExceptionResolver处理器异常解析,可以将异常映射到相应的统一错误界面,从而显示用户友好的界面(而不是给用户看到具体的错误信息);

9RequestToViewNameTranslator当处理器没有返回逻辑视图名等相关信息时,自动将请求 URL 映射为逻辑视图名;

10FlashMapManager用于管理 FlashMap 的策略接口,FlashMap 用于存储一个请求的输出,当进入另一个请求时作为该请求的输入,通常用于重定向场景,后边会细述。

到此 DispatcherServlet 我们已经了解了,接下来我们就需要把上边提到的特殊 Bean 挨个击破,那首先从控制器开始吧。

dispatcherServlet-servlet.xml (SSM maven 项目)

dispatcherServlet-servlet.xml (SSM maven 项目)

<?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"
       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.xsd">

    <!--SpringMVC的配置文件,包含网站跳转逻辑的控制 、 配置    默认规则  use-default-filters=" false"  -->
    <context:component-scan base-package="xyz.sun" use-default-filters="false">
        <!--只扫描控制器   所有标有Controller  注解的都是控制器-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
    </context:component-scan>


    <!--配置视图解析器,方便页面返回-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--两个标准配置-->
    <!--将springmvc不能处理的请求交给tomcat-->
    <mvc:default-servlet-handler />
    <!-- 能支持springmvc 更高级的一些功能 JSR303校验 快捷Ajax请求  映射动态请求  -->
    <mvc:annotation-driven />



</beans>

 

今天关于Null ModelAndView返回给DispatcherServletcontentdocument返回null的介绍到此结束,谢谢您的阅读,有关------>Servlet.service() for servlet [dispatcherServlet] in context with path [] threw excepti...、DispatcherServlet、DispatcherServlet 详解、dispatcherServlet-servlet.xml (SSM maven 项目)等更多相关知识的信息可以在本站进行查询。

本文标签: