首页 > 代码库 > SpringMVC(一)
SpringMVC(一)
1 SpringMVC框架
1.1 SpringMVC是什么?
- SpringMVC就是Spring的一个模块,提供web层的解决方案(基于MVC设计架构)。
1.2 MVC设计模式在B/S系统中的应用
- MVC是一个设计模式,在B/S系统中的应用如下图所示。
1.3 SpringMVC的框架
SpringMVC的执行步骤:
- 用户发起request请求,请求到DispatcherServlet前端控制器。
- DispatcherServlet前端控制器请求HandlerMapping处理器查找Handler。
- DispatcherServlet:前端口控制器,相当于中央调度器,各个组件都和前端控制器进行交互,降低各个组件之间的耦合。
-
HandlerMapping处理器映射器,根据URL和一些规则(xml配置、注解配置)查找Handler,将Handler返回给DispatcherServlet前端控制器。
-
DispatcherServlet前端控制器调用适配器执行Handler,有了适配器可以在适配器去扩展对不同Handler的执行方式(比如:servlet开发,注解开发)。
- 适配器执行Handler。
-
Handler是后端处理器。
-
- Handler执行完成后返回ModelAndView。
- ModelAndView:SpringMVC的一个对象,对Model和View的一个封装。
- 适配器将ModelAndView返回DispatcherServlet前端控制器。
- DispatcherServlet调用视图解析器进行视图解析,解析后生成View。
- 视图解析器会根据逻辑视图名解析出真正的视图。
- View:SpringMVC的一个封装对象,提供了很多View,比如jsp、freemaker、PDF等。
- 视图解决器给前端控制器返回View。
- 前端控制器调用view的渲染视图的方法,将模型数据填充到request域之中。
- 前端控制器,向用户响应结果(jsp页面、json数据等等)。
【总结】:
- DispatcherServlet:前端控制器。由SpringMVC提供。
- HandlerMapping:处理器映射器,由SpringMVC提供。
- HandlerAdapter:处理器适配器,由SpringMVC提供
- Handler:处理器,需要程序员开发。
- ViewResolver:视图解析器,由SpringMVC提供。
- View视图:真正的视图页面需要程序员编写。
2 SpringMVC入门程序
2.1 建立web项目并导入jar包。
2.2 配置前端控制器(在web.xml文件中)
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- 前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 加载springmvc的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 可以配置/,此工程所有请求全部由SpringMVC解析,此种方式可以实习restful方式,需要特殊处理,对静态文件不能由SpringMVC解析 可以配置*.do或*.action等等,所有请求的URL的扩展名为.do或.action之类,由SpringMVC解析 不可以配置/*,如果/*,返回的jsp也有SpringMVC解析 --> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
2.3 新建spring-mvc.xml(配置处理器映射器、处理器适配器和视图解析器)
2.3.1 配置处理器映射器
<!-- 处理器映射器 根据URL(xxx.action)匹配spring容器bean的name,找到对应的Handler --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
2.3.2 配置处理器适配器
<!-- 处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
我们查看此处理器适配器的源码:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.web.servlet.mvc; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ModelAndView; public class SimpleControllerHandlerAdapter implements HandlerAdapter { public SimpleControllerHandlerAdapter() { } public boolean supports(Object handler) { return handler instanceof Controller; } public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller)handler).handleRequest(request, response); } public long getLastModified(HttpServletRequest request, Object handler) { return handler instanceof LastModified?((LastModified)handler).getLastModified(request):-1L; } }
我们看到下面的代码
public boolean supports(Object handler) { return handler instanceof Controller; }
就知道此种适配器,要求程序员编写的handler要实现Controller接口。
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.web.servlet.mvc; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; public interface Controller { ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception; }
那么,再看此种处理器适配器的如下代码:
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller)handler).handleRequest(request, response);
就应该知道,一旦我们编写的Handler(也可以称为Controller)实现了Controller接口,那么此种适配器就可以执行我们编写的Handler了。
【注意】SpringMVC会根据HandlerMapping接口(或其子接口或实现类)判断是否是处理器映射器,会根据HandlerAdapte(或其子接口或实现类)接口判断是否是处理器适配器
2.3.3配置视图解析器
<!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 配置后缀 --> <property name="suffix" value=".jsp"/> </bean>
2.4 编写Handler
2.4.1 新建Item.java
package cn.vo;
import java.util.Date; 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(); } }
2.4.2 新建ItemController.java
package cn.action; import cn.vo.Items; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * 描述: */ public class ItemController implements Controller { @Override public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws Exception { List<Items> itemsList = new ArrayList<Items>(); 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(); modelAndView.addObject("itemsList",itemsList); modelAndView.setViewName("itemsList"); return modelAndView; } }
2.5 在spring-mvc.xml文件中配置Handler
<!-- 配置处理器 --> <bean name="/itemList.action" class="cn.action.ItemController"></bean>
2.6 在WEB-INF下新建jsp目录和itemList.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>查询商品列表</title> </head> <body> <form action="${pageContext.request.contextPath }/item/queryItem.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <td><input type="submit" value="查询"/></td> </tr> </table> 商品列表: <table width="100%" border=1> <tr> <td>商品名称</td> <td>商品价格</td> <td>生产日期</td> <td>商品描述</td> <td>操作</td> </tr> <c:forEach items="${itemsList }" var="item"> <tr> <td>${item.name }</td> <td>${item.price }</td> <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH-mm-ss"/></td> <td>${item.detail }</td> <td><a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form> </body> </html>
3 注解的映射器和适配器
3.1 DispatcherServlet.properties
- DispatcherServlet前端控制器加载DispatcherServlet.properties配置文件,从而默认加载各个组件。如果在spring-mvc.xml中配置了处理器映射器和适配器,DispatcherServlet按照Spring-mvc.xml文件中配置的信息。
# Default implementation classes for DispatcherServlet‘s strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
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
3.2 注解映射器
- 在Spring3之前默认的注解映射器如下图所示,当然在Spring3之后此注解映射器已经过期。
- Spring3之后的注解映射器,如下图所示。
- 使用RequestMappingHandlerMapping需要在Handler中使用@Controller标识此类事一个控制器,使用@requestMapping指定Handler方法所对应的URL。
3.3 注解适配器
- 在Spring3之前的默认注解适配器如下图所示,当然,现在已经过期了。
- Spring3之后默认的注解适配器
- RequestMappingHandlerAdapter不要求Handler实现任何接口,它需要和RequestMappingHandlerAdapter注解映射器配对使用,主要解析Handler方法中的形参。
3.4 修改上面的代码,该为注解方式
3.4.1 sping-mvc.xml文件
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> <context:component-scan base-package="cn.action"/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 配置后缀 --> <property name="suffix" value=".jsp"/> </bean> </beans>
3.4.2 控制器
package cn.action; import cn.vo.Items; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * 描述: */ @Controller public class ItemController { @RequestMapping(value = "/itemsList.action") public String list(Model model){ List<Items> itemsList = new ArrayList<Items>(); 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); model.addAttribute("itemsList",itemsList); return "itemsList"; } }
4 入门程序小结
- DispatcherServlet:前端控制器,相当于中央调度器,可以降低各个组件之间的耦合。
- HandlerMapping:处理器映射器,负责根据URL查找Handler。
- HandlerAdapter:处理器适配器,负责跟进适配器要求的规则去执行处理器。可以通过扩展适配器,让其支持不同的handler。
- viewRosolver:视图解析器,根据逻辑视图名解析成真正的视图。
- DispatcherServlet通过HandlerMapping查找Handler
- DispatcherServlet通过适配器去执行Handler,得到ModelAndView
- 视图解析
- 视图渲染
SpringMVC(一)