DispatcherServlet
使用SpringMVC,配置DispatcherServlet是第一步。它也就是一个Servlet,所以可以配置多个DispatcherServlet。dispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,拦截的匹配规则要自己定义,把拦截下来的请求,依据某某规则分发到目标Controller。这个某某规则是根据你使用了那个handlerMapping接口的实现类的不同而不同。
多个Servlet之间是通过名字来区别的。每一个DispatcherServlet有自己的webApplicationContext上下文对象。
在Dispatcher Serlvet的初始化过程中,框架会在Web应用的WEB_INF文件夹下寻找名为[servlet-name]-servlet.xml的配置文件,生成文件中定义的Bean。
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指明了配置文件的文件名,不使用默认配置名,使用自定义的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/springMVC.xml</param-value>
</init-param>
</servlet>
<servlet-mapping></servlet-mapping>
没有在init-param声明的话,系统就会默认使用、WEB_INF/-servlet.xml
拦截规则可以自定义
父子上下文(WebApplicationContext)
spring会创建一个WebApplicationContext上下文,称为父上下文(父容器),保存在ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);
DispatcherServlet是一个servlet,所以可以配置多个,每个DispatcherServlet都有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子容器可以访问父上下文的内容,但是父上下文不能访问子上下文的内容。它同样也是保存在ServletContext中。当一个Request对象产生时,会把这个子上下文对象保存在Request对象中。可以使用工具类取出上下文对象:
RequestContextUtils.getWebApplicationContext(request);
说明:spring没有限制必须使用父子上下文,我们可以自己决定如何使用。
方案一:传统型
父上下文保存数据源、服务层、DAO层、事务的Bean
子上下文保存MVC相关的action的Bean、
方案二:激进型
可以没有service层,name事务控制就只好上升到Action层。不要父容器,只要子容器,数据源、服务层、DAO层、事务的BEAN、Action的Bean都放在子容器中。
总结:不使用Listener监听器来加载Spring的配置文件,只使用DispatcherServlet来加载Spring的配置,不要父子上下文,只使用一个DispatcherServlet,事情就简单了。
XML配置文件的讲解
扫描指定的包中的类上的注解,常见的注解:
@Controller、:声明Action组件
@Service、:声明Service组件
@Repository、:声明Dao组件
@Component、:泛指组件、不好归类时使用
@RequestMapping(“/menu”)、:请求映射
@Resource、:用于注入按名称转配,J2ee提供,@Resource(name=“beanName”)
@Autowired、:用于按类型装配注入,Spring提供
@Transactional(rollbackFor{Exception.class})、:事务管理
@ResponseBody、
@Scope(“prototype”):设定bean的作用域:这是一种简写形式,可以通过手动配置来代替,简写形式可以让初学者快速应用到默认配置方案。会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter两个bean,是SpringMVC为@Controller分发请求所必须的。并提供了一系列的其他支持
是一种简写形式。我们可以配置多个HandlerMapping ,会为每一个HandlerMapping注入一个拦截器,当然我们也可已手动配置。
- 使用默认的Servlet来响应静态文件。
匹配URL/images/**的URL被当做静态资源,由Spring读出到内存中再响应HTTP。
如何访问到静态的文件,如JPG,js,css
如果DispatcherServlet拦截“.do”()这样有后缀的URL就不存在访问不到静态资源的问题,如果拦截的是“/”,也就是拦截了所有请求,为了实现REST风格。那么同样的“.js”和”*.css”也就被拦截了。
要解决这个问题,正常访问静态文件,找不到的话报404。
- 方案一:激活Tomcat的defaultServlet来处理静态文件。
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</sefvlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</sefvlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</sefvlet-mapping>
以上代码写在DispatcherServlet的前面,让defaultServlet先拦截请求,这样请求就不会进入Spring了,能够很好的提高性能。
2. 方案二:在Spring3.0.4以后版本提供了mvc:resource,使用方法:
<!--对静态文件的访问-->
<mvc:resources mapping="/images/**" loaction="/images/"/>
/images/**映射到ResourceHttpRequestHandler进行处理,location指定静态资源的位置。cache-period可以使得静态资源进行webcache。
出现错误时,可能是没有配置的原因。
Spring MVC快速理解
springMVC采用的模式是:Front controller+Application Controller+page Controller+Context。前端控制器+应用控制器+页面控制器(也称为动作)+上下文,责任更加明确。
使用Jsp和servlet技术的模式是Model2
Front Controller:前端控制器,负责为表现层提供统一接入点,为多个请求提供公用的逻辑,比如准备上下文。将选择具体视图和具体的功能处理分开来。
Application Controller应用控制器,前端控制器分离具体视图选择和具体功能处理之后,需要有人来管理,应用控制器就是用来选择具体视图和具体功能处理
Page Controller:页面控制器、动作、处理器:功能处理代码,收集参数、封装参数到模型,转调业务对象处理模型,返回逻辑视图名给前端控制器,由前端控制器委托给应用控制器选择具体的视图来展示。页面控制器又叫处理器或动作。
context:上下文,要展示的模型数据都可以放置在上下文。
DispatcherServlet是前段控制器的实现,提供了Spring Web MVC的集中访问点,SpringMVC也是围绕着一个Servlet进行的,它将请求分发给控制器,并提供其他功能帮助Web应用开发。并且远不止这样,spring的DispatcherServlet和Spring的IOC容器完全集成在一起,从而允许你使用spring的功能。
创建请求处理器类(编写控制器):
@Controller表明了该类是一个控制器,为了使controller能够被自动检测,必须要像web.xml文件中加入扫描的语句。@RequestMapping(“/hello world”)为控制器指定可以处理的请求URL
<context:component-scan base-package="com.springmvc.controller" />
RequestMapping及请求映射
@RequestMapping为指定控制器可以处理哪些URL请求。在控制器的类定义和方法定义出都可标注@RequestMapping
- 类定义处:提供初步的请求映射信息
- 方法处:进一步的细分映射信息
处理模型数据
- ModelAndView
一旦Controller处理完了客户的请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。从宏观角度考虑DispatcherServlet前端控制器是整个Web应用的控制器;从微观角度考虑,controller是单个Http请求处理过程中的控制器,ModelAndView是Http请求过程中返回的模型和视图。
Spring MVC概念
前端控制器,DispatchServlet是前端分发器。
HandlerAdapter是一个在DispatcherServlet内部使用的一个类。是controller的一个表现形式,在DispatcherServlet中调用的controller都是以Handler格式出现的。
HandlerInterceptor是一个拦截器的意思,是一个接口
HandlerMapping前端控制器与controller的一种映射关系,来告诉我们前端请求到达后,由哪一个controller来响应请求。
Handler执行链条 HandlerExecutionChain
preHandle->Controller method->postHandle->afterCompletion
ViewResolver帮助DispatchServlet找出合适的视图
SpringMVC的运行结构:
1.请求自用户发送过来,首先交由DispatcherServlet处理分发
2.拦截到的请求应该分发给对应的controller,这个就是靠HandlerMapping去找Controller和HandlerInterceptor
2.5DispatcherServlet是调用一般化以后的controller也就是Handler或HandlerAdapter
3.controller提供一些Model和view,返回给DispatcherServlet
4.dispatcherServlet再将内容传至视图解析器ViewResolver
基于Maven的SpringMVC环境搭建
- 下载maven,使用eclipse配置好maven
- 利用Maven创建一个项目,要开发javaWeb,选择ArtifactId是maven-archetype-webapp。
- 填写好自己创建的项目的包名等信息。
- 打开创建好的项目中的pom.xml文件,在Dependencies标签栏中添加进Spring的依赖:Group Id:org.springframework Artifact Id:spring-web version:是你下载好的Spring的对应版本,如果没有下载,可以右键pom.xml文件,选择Maven Install项。这样就可以在java library中看到所添加进来的依赖了
- 在src的main文件夹下创建java,在src下创建test文件夹,在test文件夹下创建java文件夹。
- controller应当写在src java文件夹下,view层的jsp视图应当写在webapp文件夹下WEB-INF目录下建立的view文件夹中。
- 配置web.xml文件
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 在webapp文件夹下的WEB-INF目录下写spring-mvc-servlet.xml文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.springmvc.controller" />
<bean id="viewResolver"
class="orgspringframeworkwebservletviewInternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
- 接着就可以在工程最外层运行该项目,前提当然是你已经下载好了tomcat并且配置了进来,当然你选择手动添加也是OK的。
Spring-HandlerMapping
常见的HandlerMapping共3种。BeanNameUrlHandlerMapping(默认使用),SimpleURLHandlerMapping,ControllerClassNameHandlerMapping。
- BeanNameUrlHandlerMapping
<!-- 声明HandlerMapping -->
<!-- 声明BeanNameURI处理器映射,其为默认的处理器映射-->
<bean id="beanNameUrlHandleMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--声明controller-->
<bean name="/home.action" class="spring.mvc.controller.HelloController">
- SimpleUrlHandlerMapping
<!-- 声明SimpleUrlHandlerMapping处理器映射 -->
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/a.action">homeController</prop>
<prop key="/b.action">homeController</prop>
</props>
</property>
</bean>
用户通过prop配置的key至访问页面,如果同时有了相同的URl,可以为框架自定义顺序,数字越小,优先级越高。
3. ControllerClassNameHandlerMapping
<!-- 声明ControllerClassNamedlerMapping处理器映射 -->
<bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
</bean>
控制类名处理器只需要简单声明即可使用,访问地址是带类带控制器名