Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
Spring MVC框架通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText和POI。Spring MVC 框架并不知道使用的视图,所以不会强迫开发者只使用 JSP 技术。
Spring MVC的执行流程:
1.首先浏览器向服务器发送Http request请求,请求被前端控制器(DispatcherServlet)捕获。
2.前端控制器根据xml文件中的配置(或者注解)对请求的URL进行解析,得到请求资源标识符(URI)。
3.根据该URI,调用处理器映射器(HandlerMapping)获得处理该请求的Handler以及Handler对应的拦截器,最后以 HandlerExecutionChain 对象的形式返回。
4.前端控制器根据获得的Handler,选择一个合适的处理器适配器(HandlerAdapter)去执行该Handler。
5.处理器适配器提取request中的模型数据,填充Handler入参,执行处理器(Handler)(也称之为Controller).
6.Handler(Controller)执行完成后,向处理器适配器返回一个ModelAndView对象,处理器适配器再向前端控制器返回该ModelAndView对象(ModelAndView只是一个逻辑视图)。
7.根据返回的ModelAndView,前端控制器请求一个适合的视图解析器(ViewResolver)(必须是已经注册到Spring容器中的ViewResolver)去进行视图解析,然后视图解析器向前端控制器返回一个真正的视图View(jsp)。
8.前端控制器通过Model解析出ModelAndView中的参数进行解析,最终展现出完整的View并通过Http response返回给客户端。
整理时序图
从上面的分析可以看出,springmvc有几个主要的组件,下面结合我们编程,来分析一下这几个组件:
1.前端控制器DispatcherServlet(不需要程序员开发)。
作用:接收请求,响应结果,相当于转发器,中央处理器。有了DispatcherServlet减少了其它组件之间的耦合度。
2.处理器映射器HandlerMapping(不需要程序员开发)。
作用:根据请求的url查找Handler。
3.处理器适配器HandlerAdapter(不需要程序员开发)。
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler。
4.处理器Handler(需要程序员开发)。
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler
5.视图解析器ViewResolver(不需要程序员开发)。
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
6.视图View(jsp页面需要程序员开发)。
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)
Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。是一个典型的教科书式的mvc构架,而不像struts等都是变种或者不是完全基于mvc系统的框架,对于初学者或者想了解mvc的人来说我觉得 spring是最好的,它的实现就是教科书!
Spring MVC和tapestry一样是一个纯正的servlet系统,这也是它和tapestry相比 struts所具有的优势。而且框架本身有代码,看起来容易理解。下面我来进行一个简单的示例:
先贴一下项目结构:
1.我们新建父工程maven-parent做pom依赖的统一管理
4.0.0
com.lcx.parent
maven-parent
0.0.1-SNAPSHOT
pom
4.10
4.1.3.RELEASE
3.2.8
1.2.2
1.2.15
4.0.0
0.9.5
4.2.1
5.1.32
1.6.4
2.4.2
1.1.9
0.9.1.2
4.3.5
1.2
2.5
2.0
2.5
3.3.2
1.3.2
3.1
junit
junit
${junit.version}
test
org.springframework
spring-context
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
${mybatis.spring.version}
com.github.miemiedev
mybatis-paginator
${mybatis.paginator.version}
com.github.pagehelper
pagehelper
${mybatis.pagehelper.version}
com.github.jsqlparser
jsqlparser
${jsqlparser.version}
tk.mybatis
mapper
${mybatis.mapper.version}
mysql
mysql-connector-java
${mysql.version}
com.alibaba
druid
${druid.version}
c3p0
c3p0
${c3p0.version}
org.slf4j
slf4j-log4j12
${slf4j.version}
jstl
jstl
${jstl.version}
javax.servlet
servlet-api
${servlet-api.version}
provided
javax.servlet
jsp-api
${jsp-api.version}
provided
org.apache.commons
commons-lang3
${commons-lang3.version}
org.apache.commons
commons-io
${commons-io.version}
cglib
cglib
${cglib.version}
com.fasterxml.jackson.core
jackson-databind
${jackson.version}
org.apache.httpcomponents
httpclient
${httpclient.version}
joda-time
joda-time
${joda-time.version}
${project.artifactId}
org.apache.maven.plugins
maven-resources-plugin
2.7
UTF-8
org.apache.maven.plugins
maven-compiler-plugin
3.2
1.7
1.7
UTF-8
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
2.新建maven 项目springmvc02指定打包为war,并修改pom.xml文件
pom.xml
4.0.0
com.lcx.parent
maven-parent
0.0.1-SNAPSHOT
../maven-parent/pom.xml
com.lcx.springmvc01
springmvc01
1.0.1-SNAPSHOT
war
org.springframework
spring-webmvc
org.slf4j
slf4j-log4j12
com.fasterxml.jackson.core
jackson-databind
jstl
jstl
javax.servlet
servlet-api
provided
javax.servlet
jsp-api
provided
commons-fileupload
commons-fileupload
1.3.1
maven-compiler-plugin
1.7
1.7
maven-war-plugin
2.4
3.0
org.apache.tomcat.maven
tomcat7-maven-plugin
8080
/
3.在目录src/main/resources创建log4j.properties资源文件
log4j.rootLogger=DEBUG,A1
log4j.logger.org.mybatis=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
4.在目录src/main/webapp下创建WEB-INF文件夹web.xml配置文件与springmvc-servlet.xml
web.xml
springmvc02
index.jsp
springmvc
org.springframework.web.servlet.DispatcherServlet
1
springmvc
*.do
springmvc-servlet.xml
5.在目录src/main/java新建包结构com.lcx.user.controller并创建UserController
package com.lcx.user.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/sayHello")
public String sayHello(ModelMap model) {
model.addAttribute("message", "sayHello say HelloWorld");
return "HelloWorld";
}
@RequestMapping(method = RequestMethod.GET)
public String sayHelloGET(ModelMap model) {
model.addAttribute("message", "sayHelloGET say HelloWorld");
return "HelloWorld";
}
@RequestMapping(method = RequestMethod.POST)
public String sayHelloPOST(ModelMap model) {
model.addAttribute("message", "POST say HelloWorld");
return "HelloWorld";
}
}
6.在指定目录创建index.jsp及HelloWorld.jsp
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
My JSP 'index.jsp' starting page
index.jsp默认首页
HelloWorld.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
My JSP 'HelloWorld.jsp' starting page
${message}
7.启动tomcat访问项目