1.跟踪mvc请求
请求会由DispatcherServlet分配给控制器(Controller)根据Handler mapping来确定,在Controller完成处理后,接着请求会被发送给一个视图(View)由ViewResolver来确定
2.搭建mvc
<servlet>
<servlet-name>mvc-demo</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
servlet-name 很重要 默认情况下DispatcherServlet在加载时会从一个基于servlet-name的xml文件mvc-demo-servlet.xml位于WEB-INF目录下
接下来我们必须声明DispatcherServlet处理哪些URL比较常见的DispatcherServlet匹配模式是*.htm,/*或者/app 但这些模式都存在一些问题
将其匹配到/*上的话,没有映射制定类型的响应,它表明DispatcherServlet将处理所有的请求。这会在处理图片或者样式表这样的静态资源时带来不必要的麻烦
/app模式 帮助我们区分了dispatcherServlet处理的内容和其他内容,但这样就会在URL中暴露实现的细节(具体来说是/app路径)为了隐藏/app路径通常需要复杂的URL重写技巧
为了不使用有缺陷的servlet匹配模式,更倾向使用
<servlet-mapping>
<servlet-name>mvc-demo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
通过映射到/ 声明会处理所有的请求,包括对静态资源的请求。
Spring提供了一个方便的配置,使得我们不必过于担心细节Spring的Mvc明明空间包含了一个新的<mvc:resources>元素,他会处理静态资源的请求。
<mvc:resources mapping="/resources/**" location="/resources/"></mvc:resources>
3.配置注解驱动的Spring mvc
DispatcherServlet需要咨询一个或多个处理器映射来明确地将请求分发给哪个控制器。Spring自带了多个处理器映射实现供我们选择。
BeanNameUrlHandlerMapping:根据控制器bean的名字将控制器映射到URL
ControllerBeanNameHandlerMapping:与BeanNameUrlHandlerMapping类似,根据控制器Bean的名字将控制器映射到URL。使用该处理器映射实现,
Bean的名字不需要遵循URL的约定。
ControllerClassNameHandlerMapping 通过使用控制器的类名作为URL基础将控制器映射到URL
DefaultAnnotationHandlerMapping 将请求映射给使用@RequestMapping注解控制器
SimpleUrlHandlerMapping 使用定义在Spring应用上下文的属性集合将控制器映射到URL
4.定义控制器
@Controller注解表明这是一个控制器类,这个类是@Component是注解的一种具体化,也就是说<context:component-scan>将查找使用@Component注解那样
这意味着需要在配置文件中配置一个<context:component-scan>这样Controller类将会自动被发现并注册为Bean.
@RequestMapping注解指明方法要处理的路径请求
5.解析视图
为了确定指定的请求需要使用哪个视图,DispatcherServlet会查找一个视图解析器来将控制器返回的逻辑视图名称转换成渲染结果的实际视图
实际上,视图解析器的工作是将逻辑视图的名字与org.springframework.web.servlet.View的实现相匹配。
6.完成Spring应用上下文
DispatcherServlet会根据一个xml文件来加载其Spring应用上下文,而这个文件的名字基于它的servlet-name来确定
contextLoaderListener是一个Servlet监听器,除了DispatcherServlet创建的应用上下文以外,它能够加载其他配置文件。
为了使用ContextLoadListener需要在web.xml文件中添加如下的Listener声明
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
必须告诉ContextLoaderListener需要加载那些配置文件。如果没有指定,上下文加载器会查找/WEB-INF/applicationContext.xml
这个配置文件。但这个文件本身并没有做到将应用上下文拆分为多个片段,所以我们要重写默认实现。
为了给ContextLoaderListener指定一个或多个Spring配置文件,需要在servlet上下文配置contextConfigLocation参数
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:service-context.xml
</param-value>
</context-param>
7.@RequestMapping
类级别的@RequestMapping定义了这个控制器所处理的根URL路径。最终会在Controller中添加多个处理方法,每个方法处理不同的请求,但请求必须都以
类级别@RequestMapping配置的路径名开头
方法级别的@RequestMapping缩小了类级别所定义的@RequestMapping路径匹配。method属性表明Http的请求类型
params参数能够限制处理方法只对包含特定参数的请求进行处理。
@RequestParam注解表明它的值应该根据请求的参数来获取。
在方法中可以传递Map<String,Object>或者Model参数。Model提供了几个更便利的方法来填充模型
如:addAttribute()与map的put方法所做的事情完全一样,只不过它能够自己计算出map的键部分,key为类名
@Valid注解 这表明Spitter在传入之前需要通过校验。
8.重定向
前缀redirect:说明请求将被重定向到指定路径。对于重定向的路径,将采用/xxx/{yyy}这样的形式
9.处理带有路径变量的请求
@ReqeustMapping(value="/{yyy}",method=RequestMethod.GET)
10.校验输入
@Valid注解是防御错误表单输入的第一道防线,@Valid是JSR-303的一部分。
如果校验出错的话,检验错误将会作为第二个参数以BindingResult的形式传递给方法,
如果BindingResult的hasErrors方法返回true就意味着校验失败了。
展现校验错误
为用户展现这些错误的一种方式就是通过BindingResult的getFieldError()方法来获取字段的错误
但更好的一种方式是使用Spring的表单绑定Jsp标签库
<sf:errors>
11.文件上传