Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,springMVC是spring的一个模块,提供web层解决方案。
第一步:用户发起request请求,请求至DispatcherServlet前端控制器
第二步:DispatcherServlet前端控制器请求HandlerMapping处理器映射器查找Handler
DispatcherServlet:前端控制器,相当于中央调度器,各各组件都和前端控制器进行交互,降低了各各组件之间耦合度。
第三步:HandlerMapping处理器映射器,根据url及一些配置规则(xml配置、注解配置)查找Handler,将生成的Handler对象和处理器拦截器链一并返回给DispatcherServlet前端控制器
第四步:DispatcherServlet前端控制器调用适配器执行Handler,(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)有了适配器通过适配器去扩展对不同Handler执行方式(比如:原始servlet开发,注解开发)
第五步:适配器执行具体的Handler也就是controller,将request域中的数据注入到controller方法的形参中,
第六步:Handler执行完成返回ModelAndView
ModelAndView:springmvc的一个对象,对Model和view进行封装。
第七步:适配器将ModelAndView返回给DispatcherServlet
第八步:DispatcherServlet调用视图解析器进行视图解析,解析后生成view
视图解析器根据逻辑视图名解析出真正的视图。
View:springmvc视图封装对象,提供了很多view,jsp、freemarker、pdf、excel等
第九步:ViewResolver视图解析器给前端控制器返回view
第十步:DispatcherServlet调用view的渲染视图的方法,将模型数据填充到request域。
第十一步:DispatcherServlet向用户响应结果(jsp页面、json数据等)
使用spring3.2.0(带springwebmvc模块)的jar包
在web.xml中配置:
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
springmvc
*.action
在springmvc.xml中配置:
BeanNameUrlHandlerMapping: 根据请求url(XXXX.action)匹配spring容器bean的 name
找到对应的bean(程序编写的Handler)
所有处理器映射器都实现HandlerMapping接口。
在springmvc.xml配置:
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
所有的适配器都是实现了HandlerAdapter接口。
程序编写Handler根据适配器的要求编写。
SimpleControllerHandlerAdapter适配器要求:
通过supports方法知道Handler必须要实现Controller接口:
publicboolean supports(Object handler) {
return (handlerinstanceofController);
}
public class Items {
private Integer id;
private String name;
private Float price;
private String pic;
private Date createtime;
private String detail;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic == null ? null : pic.trim();
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail == null ? null : detail.trim();
}
}
编写ItemController1.java
public class ItemController1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// 使用静态数据将商品信息列表显示在jsp页面
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
//将数据填充到request
// request.setAttribute("itemsList",itemsList);
modelAndView.addObject("itemsList", itemsList);
//指定转发的jsp页面
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
return modelAndView;
}
}
在springmvc.xml配置Handler由spring管理Handler。
<beanid="itemController1"name="/itemList.action"
class="cn.itcast.springmvc.first.ItemController1"/>
配置视图解析,能够解析jsp视图:
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
bean>
将整个入门程序加载到tomcat,然后访问:http://localhost:8080/springMVCfirst/itemList.action
根据请求url(XXXX.action)匹配spring容器bean的 name
找到对应的bean(程序编写的Handler)
<beanclass="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<propertyname="mappings">
<props>
<prop key="/itemsTest1.action">itemController1prop>
<prop key="/itemsTest2.action">itemController2prop>
props>
property>
bean>
注意:在springmvc.xml配置了多个处理器映射器,多个处理器映射器可以共存。
要求程序编写的Handler(Controller)需要实现 Controller接口。
在springmvc.xml配置:HttpRequestHandlerAdapter
要求Handler 实现HttpRequestHandler接口
这里就相当于使用原始servlet开发
public class ItemController2 implements HttpRequestHandler {
public void handleRequest(HttpServletRequestrequest, HttpServletResponse response)
throws ServletException, IOException {
// 使用静态数据将商品信息列表显示在jsp页面
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
request.setAttribute("itemsList", itemsList);
//转发到jsp页面
request.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(request, response);
}
}
<beanid="itemController2"class="cn.itcast.springmvc.first.ItemController2">bean>
映射器可以随便使用哪个配置这里使用SimpleUrlHandlerMapping映射器
key="/itemsTest2.action">itemController2
DispatcherServlet.properoties 这个配置文件是DispatcherServlet前端控制器加载默认加载配置文件,里面配置了各种处理器的映射器和适配器从而默认加载各各组件。
如果在springmvc.xml中配置了处理器映射器和适配器,则以sprintmvc.xml中配置的为准
spring3.1之前默认加载映射器是
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping,
3.1之后要使用:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
使用RequestMappingHandlerMapping需要在Handler 中使用@controller标识此类是一个控制器,使用@requestMapping指定Handler方法所对应的url。
spring3.1之前默认加载映射器是
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter,
3.1之后要使用:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
RequestMappingHandlerAdapter,不要求Handler实现任何接口,它需要和RequestMappingHandlerMapping注解映射器配对使用,主要解析Handler方法中的形参。
@Controller
public class ItemController3 {
//商品列表,@RequestMapping中url建议和方法名一致,方便开发维护
@RequestMapping("/queryItems")
public ModelAndView queryItems(){
// 使用静态数据将商品信息列表显示在jsp页面
// 商品列表
List itemsList = new ArrayList();
Itemsitems_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList", itemsList);
//指定逻辑视图名
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
return modelAndView;
}
//其他方法
}
<context:component-scanbase-package="cn.itcast.springmvc.first"/>
建议使用组件扫描,组件扫描可以扫描@Controller、@Service、@component、@Repsitory
DispatcherServlet:前端控制器,相当于中央调度器,可以降低组件之间的耦合度。
HandlerMapping:处理器映射器,负责根据url查找Handler
HandlerAdapter:处理器适配器,负责根据适配器要求的规则去执行处理器。可以通过扩展适配器支持不同类型的Handler。
viewResolver:视图解析器,根据逻辑视图名解析成真正的视图,
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix"value="/WEB-INF/jsp/"/>
<propertyname="suffix"value=".jsp"/>
bean>
真正的视图=前缀+逻辑视图名+后缀
框架源码分析
1、DispatcherServlet在doDispatch(HttpServletRequestrequest, HttpServletResponse response)z这个初始化的方法中通过mappedHandler查找HandlerExecutionChina
2、DispatcherServlet通过适配器去执行Handler,得到ModelAndview
3、视图解析
视图解析完成得到一个view:
4、进行视图渲染
将Model中的数据填充到request域。