1. 學習計划
第一天
1、SpringMVC介紹
2、入門程序
3、SpringMVC架構講解
a) 框架結構
b) 組件說明
4、SpringMVC整合MyBatis
5、參數綁定
a) SpringMVC默認支持的類型
b) 簡單數據類型
c) Pojo類型
d) Pojo包裝類型
e) 自定義參數綁定
6、SpringMVC和Struts2的區別
第二天
1、高級參數綁定
a) 數組類型的參數綁定
b) List類型的綁定
2、@RequestMapping注解的使用
3、Controller方法返回值
4、SpringMVC中異常處理
5、圖片上傳處理
6、Json數據交互
7、SpringMVC實現RESTful
8、攔截器
2. Spring入門
2.1. Springmvc是什么
Spring web mvc和Struts2都屬於表現層的框架,它是Spring框架的一部分,我們可以從Spring的整體結構中看得出來,如下圖:
2.2. Springmvc處理流程
如下圖所示:
2.3. 入門程序
需求:使用瀏覽器顯示商品列表
2.3.1. 創建web工程
springMVC是表現層框架,需要搭建web工程開發。
如下圖創建動態web工程:
輸入工程名,選擇配置Tomcat(如果已有,則直接使用),如下圖:
配置Tomcat,如下圖:
選擇准備好的Tomcat,這里用的是Tomcat7,如下圖:
選擇成功,點擊Finish,如下圖:
選擇剛剛設置成功的Tomcat,如下圖:
如下圖選擇web的版本是2.5,可以自動生成web.xml配置文件,
創建效果如下圖:
2.3.2. 導入jar包
從課前資料中導入springMVC的jar包,位置如下圖:
復制jar到lib目錄,工程直接加載jar包,如下圖:
2.3.3. 加入配置文件
創建config資源文件夾,存放配置文件,如下圖:
2.3.3.1. 創建springmvc.xml
創建SpringMVC的核心配置文件
SpringMVC本身就是Spring的子項目,對Spring兼容性很好,不需要做很多配置。
這里只配置一個Controller掃描就可以了,讓Spring對頁面控制層Controller進行管理。
創建springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置controller掃描包 --> <context:component-scan base-package="cn.itcast.springmvc.controller" /> </beans>
配置文件需要的約束文件,位置如下圖:
創建包cn.itcast.springmvc.controller
效果如下圖:
2.3.3.2. 配置前端控制器
配置SpringMVC的前端控制器DispatcherServlet
在web.xml中
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>springmvc-first</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置SpringMVC前端控制器 --> <servlet> <servlet-name>springmvc-first</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定SpringMVC配置文件 --> <!-- SpringMVC的配置文件的默認路徑是/WEB-INF/${servlet-name}-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc-first</servlet-name> <!-- 設置所有以action結尾的請求進入SpringMVC --> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
2.3.4. 加入jsp頁面
把參考資料中的itemList.jsp復制到工程的/WEB-INF/jsp目錄下,如下圖:
2.3.5. 實現顯示商品列表頁
2.3.5.1. 創建pojo
分析頁面,查看頁面需要的數據,如下圖:
創建商品pojo
public class Item { // 商品id private int id; // 商品名稱 private String name; // 商品價格 private double price; // 商品創建時間 private Date createtime; // 商品描述 private String detail; 創建帶參數的構造器 set/get。。。 }
2.3.5.2. 創建ItemController
ItemController是一個普通的java類,不需要實現任何接口。
需要在類上添加@Controller注解,把Controller交由Spring管理
在方法上面添加@RequestMapping注解,里面指定請求的url。其中“.action”可以加也可以不加。
@Controller public class ItemController { // @RequestMapping:里面放的是請求的url,和用戶請求的url進行匹配 // action可以寫也可以不寫 @RequestMapping("/itemList.action") public ModelAndView queryItemList() { // 創建頁面需要顯示的商品數據 List<Item> list = new ArrayList<>(); list.add(new Item(1, "1華為 榮耀8", 2399, new Date(), "質量好!1")); list.add(new Item(2, "2華為 榮耀8", 2399, new Date(), "質量好!2")); list.add(new Item(3, "3華為 榮耀8", 2399, new Date(), "質量好!3")); list.add(new Item(4, "4華為 榮耀8", 2399, new Date(), "質量好!4")); list.add(new Item(5, "5華為 榮耀8", 2399, new Date(), "質量好!5")); list.add(new Item(6, "6華為 榮耀8", 2399, new Date(), "質量好!6")); // 創建ModelAndView,用來存放數據和視圖 ModelAndView modelAndView = new ModelAndView(); // 設置數據到模型中 modelAndView.addObject("list", list); // 設置視圖jsp,需要設置視圖的物理地址 modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp"); return modelAndView; } }
2.3.6. 啟動項目測試
啟動項目,瀏覽器訪問地址
http://127.0.0.1:8080/springmvc-first/itemList.action
效果如下圖:
為什么可以用呢?我們需要分析一下springMVC的架構圖。
3. Springmvc架構
3.1. 框架結構
框架結構如下圖:
3.2. 架構流程
1、 用戶發送請求至前端控制器DispatcherServlet
2、 DispatcherServlet收到請求調用HandlerMapping處理器映射器。
3、 處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一並返回給DispatcherServlet。
4、 DispatcherServlet通過HandlerAdapter處理器適配器調用處理器
5、 執行處理器(Controller,也叫后端控制器)。
6、 Controller執行完成返回ModelAndView
7、 HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
8、 DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器
9、 ViewReslover解析后返回具體View
10、 DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)。
11、 DispatcherServlet響應用戶
3.3. 組件說明(一個中心三個基本點)
以下組件通常使用框架提供實現:
黃色是三大組件,綠色是我們要寫的,白色部分是中心
u DispatcherServlet:前端控制器
用戶請求到達前端控制器,它就相當於mvc模式中的c,dispatcherServlet是整個流程控制的中心,由它調用其它組件處理用戶的請求,dispatcherServlet的存在降低了組件之間的耦合性。
u HandlerMapping:處理器映射器
HandlerMapping負責根據用戶請求url找到Handler即處理器,springmvc提供了不同的映射器實現不同的映射方式,例如:配置文件方式,實現接口方式,注解方式等。
u Handler:處理器
Handler 是繼DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。
由於Handler涉及到具體的用戶業務請求,所以一般情況需要程序員根據業務需求開發Handler。
u HandlAdapter:處理器適配器
通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行。
下圖是許多不同的適配器,最終都可以使用usb接口連接
u ViewResolver:視圖解析器
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,再生成View視圖對象,最后對View進行渲染將處理結果通過頁面展示給用戶。
u View:視圖
springmvc框架提供了很多的View視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。我們最常用的視圖就是jsp。
一般情況下需要通過頁面標簽或頁面模版技術將模型數據通過頁面展示給用戶,需要由程序員根據業務需求開發具體的頁面。
說明:在springmvc的各個組件中,處理器映射器、處理器適配器、視圖解析器稱為springmvc的三大組件。 需要用戶開發的組件有handler、view |
3.4. 默認加載的組件
我們沒有做任何配置,就可以使用這些組件
因為框架已經默認加載這些組件了,配置文件位置如下圖:
# 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.5. 組件掃描器
使用組件掃描器省去在spring容器配置每個Controller類的繁瑣。
使用<context:component-scan>自動掃描標記@Controller的控制器類,
在springmvc.xml配置文件中配置如下:
<!-- 配置controller掃描包,多個包之間用,分隔 --> <context:component-scan base-package="cn.itcast.springmvc.controller" />
3.6. 注解映射器和適配器
3.6.1. 配置處理器映射器
注解式處理器映射器,對類中標記了@ResquestMapping的方法進行映射。根據@ResquestMapping定義的url匹配@ResquestMapping標記的方法,匹配成功返回HandlerMethod對象給前端控制器。
HandlerMethod對象中封裝url對應的方法Method。
從spring3.1版本開始,廢除了DefaultAnnotationHandlerMapping的使用,推薦使用RequestMappingHandlerMapping完成注解式處理器映射。
在springmvc.xml配置文件中配置如下:
<!-- 配置處理器映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
注解描述:
@RequestMapping:定義請求url到處理器功能方法的映射
3.6.2. 配置處理器適配器
注解式處理器適配器,對標記@ResquestMapping的方法進行適配。
從spring3.1版本開始,廢除了AnnotationMethodHandlerAdapter的使用,推薦使用RequestMappingHandlerAdapter完成注解式處理器適配。
在springmvc.xml配置文件中配置如下:
<!-- 配置處理器適配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
3.6.3. 注解驅動
直接配置處理器映射器和處理器適配器比較麻煩,可以使用注解驅動來加載。
SpringMVC使用<mvc:annotation-driven>自動加載RequestMappingHandlerMapping和RequestMappingHandlerAdapter
可以在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解處理器和適配器的配置。
<!-- 注解驅動 --> <mvc:annotation-driven />
3.7. 視圖解析器
視圖解析器使用SpringMVC框架默認的InternalResourceViewResolver,這個視圖解析器支持JSP視圖解析
在springmvc.xml配置文件中配置如下:
<!-- Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" -> "/WEB-INF/jsp/test.jsp" --> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置邏輯視圖的前綴 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 配置邏輯視圖的后綴 --> <property name="suffix" value=".jsp" /> </bean>
邏輯視圖名需要在controller中返回ModelAndView指定,比如邏輯視圖名為ItemList,則最終返回的jsp視圖地址:
“WEB-INF/jsp/itemList.jsp”
最終jsp物理地址:前綴+邏輯視圖名+后綴
3.7.1. 修改ItemController
修改ItemController中設置視圖的代碼
// @RequestMapping:里面放的是請求的url,和用戶請求的url進行匹配 // action可以寫也可以不寫 @RequestMapping("/itemList.action") public ModelAndView queryItemList() { // 創建頁面需要顯示的商品數據 List<Item> list = new ArrayList<>(); list.add(new Item(1, "1華為 榮耀8", 2399, new Date(), "質量好!1")); list.add(new Item(2, "2華為 榮耀8", 2399, new Date(), "質量好!2")); list.add(new Item(3, "3華為 榮耀8", 2399, new Date(), "質量好!3")); list.add(new Item(4, "4華為 榮耀8", 2399, new Date(), "質量好!4")); list.add(new Item(5, "5華為 榮耀8", 2399, new Date(), "質量好!5")); list.add(new Item(6, "6華為 榮耀8", 2399, new Date(), "質量好!6")); // 創建ModelAndView,用來存放數據和視圖 ModelAndView modelAndView = new ModelAndView(); // 設置數據到模型中 modelAndView.addObject("itemList", list); // 設置視圖jsp,需要設置視圖的物理地址 // modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp"); // 配置好視圖解析器前綴和后綴,這里只需要設置邏輯視圖就可以了。 // 視圖解析器根據前綴+邏輯視圖名+后綴拼接出來物理路徑 modelAndView.setViewName("itemList"); return modelAndView; }
3.7.2. 效果
效果和之前一樣,如下圖:
4. 整合mybatis
為了更好的學習 springmvc和mybatis整合開發的方法,需要將springmvc和mybatis進行整合。
整合目標:控制層采用springmvc、持久層使用mybatis實現。
4.1. 創建數據庫表
sql腳本,位置如下圖:
創建數據庫表springmvc,導入到數據庫中,如下圖:
4.2. 需要的jar包
- spring(包括springmvc)
- mybatis
- mybatis-spring整合包
- 數據庫驅動
- 第三方連接池。
jar包位置如下圖:
4.3. 整合思路
Dao層:
1、SqlMapConfig.xml,空文件即可,但是需要文件頭。
2、applicationContext-dao.xml
a) 數據庫連接池
b) SqlSessionFactory對象,需要spring和mybatis整合包下的。
c) 配置mapper文件掃描器。
Service層:
1、applicationContext-service.xml包掃描器,掃描@service注解的類。
2、applicationContext-trans.xml配置事務。
Controller層:
1、Springmvc.xml
a) 包掃描器,掃描@Controller注解的類。
b) 配置注解驅動
c) 配置視圖解析器
Web.xml文件:
1、配置spring
2、配置前端控制器。
4.4. 創建工程
創建動態web工程springmvc-web,如下圖:
4.5. 加入jar包
復制jar包到/WEB-INF/lib中
工程自動加載jar包
4.6. 加入配置文件
創建資源文件夾config
在其下創建mybatis和spring文件夾,用來存放配置文件,如下圖:
4.6.1. sqlMapConfig.xml
使用逆向工程來生成Mapper相關代碼,不需要配置別名。
在config/mybatis下創建SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration>
4.6.2. applicationContext-dao.xml
配置數據源、配置SqlSessionFactory、mapper掃描器。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 加載配置文件 --> <context:property-placeholder location="classpath:db.properties" /> <!-- 數據庫連接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxActive" value="10" /> <property name="maxIdle" value="5" /> </bean> <!-- 配置SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 數據庫連接池 --> <property name="dataSource" ref="dataSource" /> <!-- 加載mybatis的全局配置文件 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> </bean> <!-- 配置Mapper掃描 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 配置Mapper掃描包 --> <property name="basePackage" value="cn.itcast.ssm.mapper" /> </bean> </beans>
4.6.3. db.properties
配置數據庫相關信息
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
4.6.4. applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 配置service掃描 --> <context:component-scan base-package="cn.itcast.ssm.service" /> </beans>
4.6.5. applicationContext-trans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 數據源 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- 通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 傳播行為 --> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> <tx:method name="query*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> <!-- 切面 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.ssm.service.*.*(..))" /> </aop:config> </beans>
或者使用注解式的事務開發:
4.6.6. springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置controller掃描包 --> <context:component-scan base-package="cn.itcast.ssm.controller" /> <!-- 注解驅動 --> <mvc:annotation-driven /> <!-- Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" -> "/WEB-INF/jsp/test.jsp" --> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置邏輯視圖的前綴 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 配置邏輯視圖的后綴 --> <property name="suffix" value=".jsp" /> </bean> </beans>
4.6.7. web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>springmvc-web</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext*.xml</param-value> </context-param> <!-- 使用監聽器加載Spring配置文件 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置SrpingMVC的前端控制器 --> <servlet> <servlet-name>springmvc-web</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc-web</servlet-name> <!-- 配置所有以action結尾的請求進入SpringMVC --> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
4.7. 加入jsp頁面
復制學習資料的itemList.jsp和itemEdit.jsp到工程中
4.8. 效果
配置完效果如下圖:
5. 實現商品列表顯示
5.1. 需求
實現商品查詢列表,從mysql數據庫查詢商品信息。
5.2. DAO開發
使用逆向工程,生成代碼
注意修改逆向工程的配置文件,參考MyBatis第二天
逆向工程生成代碼如下圖:
5.3. ItemService接口
public interface ItemService { /** * 查詢商品列表 * * @return */ List<Item> queryItemList(); }
5.4. ItemServiceImpl實現類
@Service public class ItemServiceImpl implements ItemService { @Autowired private ItemMapper itemMapper; @Override public List<Item> queryItemList() { // 從數據庫查詢商品數據 List<Item> list = this.itemMapper.selectByExample(null); return list; } }
5.5. ItemController
@Controller public class ItemController { @Autowired private ItemService itemService; /** * 顯示商品列表 * * @return */ @RequestMapping("/itemList") public ModelAndView queryItemList() { // 獲取商品數據 List<Item> list = this.itemService.queryItemList(); ModelAndView modelAndView = new ModelAndView(); // 把商品數據放到模型中 modelAndView.addObject("itemList", list); // 設置邏輯視圖 modelAndView.setViewName("itemList"); return modelAndView; } }
5.6. 測試
訪問url:
http://127.0.0.1:8080/springmvc-web/itemList.action
效果如下圖:
6. 參數綁定
6.1. 默認支持的參數類型
6.1.1. 需求
打開商品編輯頁面,展示商品信息。
6.1.2. 需求分析
編輯商品信息,首先要顯示商品詳情
需要根據商品id查詢商品信息,然后展示到頁面。
請求的url:/itemEdit.action
參數:id(商品id)
響應結果:商品編輯頁面,展示商品詳細信息。
6.1.3. ItemService接口
編寫ItemService接口如下圖:
6.1.4. ItemServiceImpl實現類
@Override public Item queryItemById(int id) { Item item = this.itemMapper.selectByPrimaryKey(id); return item; }
6.1.5. ItemController
頁面點擊修改按鈕,發起請求
http://127.0.0.1:8080/springmvc-web/itemEdit.action?id=1
需要從請求的參數中把請求的id取出來。
Id包含在Request對象中。可以從Request對象中取id。
想獲得Request對象只需要在Controller方法的形參中添加一個參數即可。Springmvc框架會自動把Request對象傳遞給方法。
代碼實現
/** * 根據id查詢商品 * * @param request * @return */ @RequestMapping("/itemEdit") public ModelAndView queryItemById(HttpServletRequest request) { // 從request中獲取請求參數 String strId = request.getParameter("id"); Integer id = Integer.valueOf(strId); // 根據id查詢商品數據 Item item = this.itemService.queryItemById(id); // 把結果傳遞給頁面 ModelAndView modelAndView = new ModelAndView(); // 把商品數據放在模型中 modelAndView.addObject("item", item); // 設置邏輯視圖 modelAndView.setViewName("itemEdit"); return modelAndView; }
6.1.6. 默認支持的參數類型
處理器形參中添加如下類型的參數處理適配器會默認識別並進行賦值。
6.1.6.1. HttpServletRequest
通過request對象獲取請求信息
6.1.6.2. HttpServletResponse
通過response處理響應信息
6.1.6.3. HttpSession
通過session對象得到session中存放的對象
6.1.7. Model/ModelMap
6.1.7.1. Model
除了ModelAndView以外,還可以使用Model來向頁面傳遞數據,
Model是一個接口,在參數里直接聲明model即可。
如果使用Model則可以不使用ModelAndView對象,Model對象可以向頁面傳遞數據,View對象則可以使用String返回值替代。
不管是Model還是ModelAndView,其本質都是使用Request對象向jsp傳遞數據。
代碼實現:
/** * 根據id查詢商品,使用Model * * @param request * @param model * @return */ @RequestMapping("/itemEdit") public String queryItemById(HttpServletRequest request, Model model) { // 從request中獲取請求參數 String strId = request.getParameter("id"); Integer id = Integer.valueOf(strId); // 根據id查詢商品數據 Item item = this.itemService.queryItemById(id); // 把結果傳遞給頁面 // ModelAndView modelAndView = new ModelAndView(); // 把商品數據放在模型中 // modelAndView.addObject("item", item); // 設置邏輯視圖 // modelAndView.setViewName("itemEdit"); // 把商品數據放在模型中 model.addAttribute("item", item); return "itemEdit"
6.1.7.2. ModelMap
ModelMap是Model接口的實現類,也可以通過ModelMap向頁面傳遞數據
使用Model和ModelMap的效果一樣,如果直接使用Model,springmvc會實例化ModelMap。
代碼實現:
/** * 根據id查詢商品,使用ModelMap * * @param request * @param model * @return */ @RequestMapping("/itemEdit") public String queryItemById(HttpServletRequest request, ModelMap model) { // 從request中獲取請求參數 String strId = request.getParameter("id"); Integer id = Integer.valueOf(strId); // 根據id查詢商品數據 Item item = this.itemService.queryItemById(id); // 把結果傳遞給頁面 // ModelAndView modelAndView = new ModelAndView(); // 把商品數據放在模型中 // modelAndView.addObject("item", item); // 設置邏輯視圖 // modelAndView.setViewName("itemEdit"); // 把商品數據放在模型中 model.addAttribute("item", item); return "itemEdit"; }
6.2. 綁定簡單類型
當請求的參數名稱和處理器形參名稱一致時會將請求參數與形參進行綁定。
這樣,從Request取參數的方法就可以進一步簡化。
/** * 根據id查詢商品,綁定簡單數據類型 * * @param id * @param model * @return */ @RequestMapping("/itemEdit") public String queryItemById(int id, ModelMap model) { // 根據id查詢商品數據 Item item = this.itemService.queryItemById(id); // 把商品數據放在模型中 model.addAttribute("item", item); return "itemEdit"; }
6.2.1. 支持的數據類型
參數類型推薦使用包裝數據類型,因為基礎數據類型不可以為null
整形:Integer、int
字符串:String
單精度:Float、float
雙精度:Double、double
布爾型:Boolean、boolean
說明:對於布爾類型的參數,請求的參數值為true或false。或者1或0
請求url:
http://localhost:8080/xxx.action?id=2&status=false
處理器方法:
public String editItem(Model model,Integer id,Boolean status)
6.2.2. @RequestParam
使用@RequestParam常用於處理簡單類型的綁定。
value:參數名字,即入參的請求參數名字,如value=“itemId”表示請求的參數 區中的名字為itemId的參數的值將傳入
required:是否必須,默認是true,表示請求中一定要有相應的參數,否則將報錯
TTP Status 400 - Required Integer parameter 'XXXX' is not present
defaultValue:默認值,表示如果請求中沒有同名參數時的默認值
定義如下:
@RequestMapping("/itemEdit") public String queryItemById(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id, ModelMap modelMap) { // 根據id查詢商品數據 Item item = this.itemService.queryItemById(id); // 把商品數據放在模型中 modelMap.addAttribute("item", item); return "itemEdit"; }
6.3. 綁定pojo類型
6.3.1. 需求
將頁面修改后的商品信息保存到數據庫中。
6.3.2. 需求分析
請求的url:/updateItem.action
參數:表單中的數據。
響應內容:更新成功頁面
6.3.3. 使用pojo接收表單數據
如果提交的參數很多,或者提交的表單中的內容很多的時候,可以使用簡單類型接受數據,也可以使用pojo接收數據。
要求:pojo對象中的屬性名和表單中input的name屬性一致。
頁面定義如下圖:
Pojo(逆向工程生成)如下圖:
請求的參數名稱和pojo的屬性名稱一致,會自動將請求參數賦值給pojo的屬性。
6.3.4. ItemService接口
ItemService里編寫接口方法
/** * 根據id更新商品 * * @param item */ void updateItemById(Item item);
6.3.5. ItemServiceImpl實現類
ItemServiceImpl里實現接口方法
使用updateByPrimaryKeySelective(item)方法,忽略空參數
@Override public void updateItemById(Item item) { this.itemMapper.updateByPrimaryKeySelective(item); }
6.3.6. ItemController
/** * 更新商品,綁定pojo類型 * * @param item * @param model * @return */ @RequestMapping("/updateItem") public String updateItem(Item item) { // 調用服務更新商品 this.itemService.updateItemById(item); // 返回邏輯視圖 return "success"; }
注意:
提交的表單中不要有日期類型的數據,否則會報400錯誤。如果想提交日期類型的數據需要用到后面的自定義參數綁定的內容。
6.3.7. 編寫success頁面
如下圖創建success.jsp頁面
頁面代碼:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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>Insert title here</title> </head> <body> <h1>商品修改成功!</h1> </body> </html>
6.3.8. 解決post亂碼問題
提交發現,保存成功,但是保存的是亂碼
在web.xml中加入:
<!-- 解決post亂碼問題 --> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!-- 設置編碼參是UTF8 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
以上可以解決post請求亂碼問題。
對於get請求中文參數出現亂碼解決方法有兩個:
修改tomcat配置文件添加編碼與工程編碼一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
另外一種方法對參數進行重新編碼:
String userName new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默認編碼,需要將tomcat編碼后的內容按utf-8編碼
6.4. 綁定包裝pojo
6.4.1. 需求
使用包裝的pojo接收商品信息的查詢條件。
6.4.2. 需求分析
包裝對象定義如下:
public class QueryVo { private Item item; set/get。。。 }
頁面定義如下圖:
6.4.3. 接收查詢條件
// 綁定包裝數據類型 @RequestMapping("/queryItem") public String queryItem(QueryVo queryVo) { System.out.println(queryVo.getItem().getId()); System.out.println(queryVo.getItem().getName()); return "success"; }
6.5. 自定義參數綁定
6.5.1. 需求
在商品修改頁面可以修改商品的生產日期,並且根據業務需求自定義日期格式。
6.5.2. 需求分析
由於日期數據有很多種格式,springmvc沒辦法把字符串轉換成日期類型。所以需要自定義參數綁定。
前端控制器接收到請求后,找到注解形式的處理器適配器,對RequestMapping標記的方法進行適配,並對方法中的形參進行參數綁定。可以在springmvc處理器適配器上自定義轉換器Converter進行參數綁定。
一般使用<mvc:annotation-driven/>注解驅動加載處理器適配器,可以在此標簽上進行配置。
6.5.3. 修改jsp頁面
如下圖修改itemEdit.jsp頁面,顯示時間
6.5.4. 自定義Converter
//Converter<S, T> //S:source,需要轉換的源的類型 //T:target,需要轉換的目標類型 public class DateConverter implements Converter<String, Date> { @Override public Date convert(String source) { try { // 把字符串轉換為日期類型 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss"); Date date = simpleDateFormat.parse(source); return date; } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 如果轉換異常則返回空 return null; } }
6.5.5. 配置Converter
我們同時可以配置多個的轉換器。
類似下圖的usb設備,可以接入多個usb設備
<!-- 配置注解驅動 --> <!-- 如果配置此標簽,可以不用配置... --> <mvc:annotation-driven conversion-service="conversionService" /> <!-- 轉換器配置 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itcast.springmvc.converter.DateConverter" /> </set> </property> </bean>
6.5.6. 配置方式2(了解)
<!--注解適配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer" ref="customBinder"></property> </bean> <!-- 自定義webBinder --> <bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="conversionService" ref="conversionService" /> </bean> <!-- 轉換器配置 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itcast.springmvc.convert.DateConverter" /> </set> </property> </bean>
注意:此方法需要獨立配置處理器映射器、適配器,
不再使用<mvc:annotation-driven/>
7. springmvc與struts2不同
1、 springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過濾器。
2、 springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,可以設計為單例或多例(建議單例),struts2是基於類開發,傳遞參數是通過類的屬性,只能設計為多例。
3、 Struts采用值棧存儲請求和響應的數據,通過OGNL存取數據, springmvc通過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最后又將ModelAndView中的模型數據通過request域傳輸到頁面。Jsp視圖解析器默認使用jstl。