SpringMVC基本教程

Spring web mvc介紹

⒈ Springmvc是什麼?
Spring web mvc和Struts2都屬於表現層的框架,它是Spring框架的一部分,我們可以從Spring的整體結構中看得出來:

⒉ SpringMVC處理流程


入門程序

⒈ 開發環境,本教程使用環境:
Jdk:jdk1.7.0_72
Eclipse:mars
Tomcat:apache-tomcat-7.0.53
Springmvc:4.1.3
⒉ 需求
使用springmvc實現商品列表的展示。
⒊ 需求分析
請求的url:/itemList.action
參數:無
數據:靜態數據
⒋ 開發步驟
第一步:創建一個javaweb工程
第二步:導入jar包

第三步:創建itemList.jsp

第四步:創建ItemsController
ItemController是一個普通的java類,不需要實現任何接口,只需要在類上添加@Controller註解即可。@RequestMapping註解指定請求的url,其中“.action”可以加也可以不加。在ModelAndView對象中,將視圖設置爲“/WEB-INF/jsp/itemList.jsp”

@Controller
public class ItemController {

	@RequestMapping("/itemList")
	public ModelAndView itemList() throws Exception {
		
		List<Items> itemList = new ArrayList<>();
		
		//商品列表
		Items items_1 = new Items();
		items_1.setName("聯想筆記本_3");
		items_1.setPrice(6000f);
		items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");
		
		Items items_2 = new Items();
		items_2.setName("蘋果手機");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6蘋果手機!");
		
		itemList.add(items_1);
		itemList.add(items_2);
		//創建modelandView對象
		ModelAndView modelAndView = new ModelAndView();
		//添加model
		modelAndView.addObject("itemList", itemList);
		//添加視圖
		modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
//		modelAndView.setViewName("itemsList");	
		return modelAndView;
	}

}

商品數據使用Items類描述,可以使用參考資料中提供的pojo類。
第五步:創建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:dubbo="http://code.alibabatech.com/schema/dubbo" 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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
        
	<context:component-scan base-package="cn.itcast.springmvc.controller"/>
	
</beans>

第六步:配置前端控制器
在web.xml中添加DispatcherServlet的配置。

<!-- 前端控制器 -->
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:springmvc.xml</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>

Springmvc架構

⒈ 框架結構

⒉ 架構流程
①用戶發送請求至前端控制器DispatcherServlet。
②DispatcherServlet收到請求調用HandlerMapping處理器映射器。
③處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
④DispatcherServlet通過HandlerAdapter處理器適配器調用處理器。
⑤執行處理器(Controller,也叫後端控制器)。
⑥Controller執行完成返回ModelAndView。
⑦HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
⑧DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。
⑨ViewReslover解析後返回具體View。
⑩DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)。
⑪DispatcherServlet響應用戶。

⒊ 組件說明
以下組件通常使用框架提供實現:
⑴ DispatcherServlet:前端控制器
用戶請求到達前端控制器,它就相當於mvc模式中的c,dispatcherServlet是整個流程控制的調度,由它調用其它組件處理用戶的請求,dispatcherServlet的存在降低了組件之間的耦合性。
⑵ HandlerMapping:處理器映射器
HandlerMapping負責根據用戶請求找到Handler即處理器,springmvc提供了不同的映射iaod器實現不同的映射方式,例如:配置文件方式,實現接口方式,註解方式等。
⑶ Handler:處理器
Handler 是繼DispatcherServlet前端控制器的後端控制器,在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。
由於Handler涉及到具體的用戶業務請求,所以一般情況需要程序員根據業務需求開發Handler。
⑷HandlAdapter:處理器適配器
通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行
⑸View Resolver:視圖解析器
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,再生成View視圖對象,最後對View進行渲染將處理結果通過頁面展示給用戶。 
⑹View:視圖
springmvc框架提供了很多的View視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。我們最常用的視圖就是jsp。
一般情況下需要通過頁面標籤或頁面模版技術將模型數據通過頁面展示給用戶,需要由程序員根據業務需求開發具體的頁面。


說明:在springmvc的各個組件中,處理器映射器、處理器適配器、視圖解析器稱爲springmvc的三大組件。
需要用戶開放的組件有handler、view。

⒋ 框架默認加載組件

⒌ 註解映射器和適配器
⑴ 組件掃描器
    使用組件掃描器省去在spring容器配置每個controller類的繁瑣。使用<context:component-scan>自動掃描標記@controller的控制器類,配置如下:
<!-- 掃描controller註解,多個包中間使用半角逗號分隔 -->

  <context:component-scan base-package="cn.itcast.springmvc.controller.first"/>

⑵ RequestMappingHandlerMapping
    註解式處理器映射器,對類中標記@ResquestMapping的方法進行映射,根據ResquestMapping定義的url匹配ResquestMapping標記的方法,匹配成功返回HandlerMethod對象給前端控制器,HandlerMethod對象中封裝url對應的方法Method。 
從spring3.1版本開始,廢除了DefaultAnnotationHandlerMapping的使用,推薦使用RequestMappingHandlerMapping完成註解式處理器映射。
配置如下:

<!--註解映射器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

註解描述:
@RequestMapping:定義請求url到處理器功能方法的映射
 ⑶ RequestMappingHandlerAdapter
註解式處理器適配器,對標記@ResquestMapping的方法進行適配。
從spring3.1版本開始,廢除了AnnotationMethodHandlerAdapter的使用,推薦使用RequestMappingHandlerAdapter完成註解式處理器適配。
配置如下:

<!--註解適配器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

⑷ <mvc:annotation-driven>
springmvc使用<mvc:annotation-driven>自動加載RequestMappingHandlerMapping和RequestMappingHandlerAdapter,可用在springmvc.xml配置文件中使用<mvc:annotation-driven>替代註解處理器和適配器的配置。
⒍ 視圖解析器
在springmvc.xml文件配置如下:

  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

InternalResourceViewResolver:支持JSP視圖解析
viewClass:JstlView表示JSP模板頁面需要使用JSTL標籤庫,所以classpath中必須包含jstl的相關jar 包。此屬性可以不設置,默認爲JstlView。
prefix 和suffix:查找視圖頁面的前綴和後綴,最終視圖的址爲:
前綴+邏輯視圖名+後綴,邏輯視圖名需要在controller中返回ModelAndView指定,比如邏輯視圖名爲hello,則最終返回的jsp視圖地址 “WEB-INF/jsp/hello.jsp”


整合mybatis

爲了更好的學習 springmvc和mybatis整合開發的方法,需要將springmvc和mybatis進行整合。
整合目標:控制層採用springmvc、持久層使用mybatis實現。
⒈ 需求
實現商品查詢列表,從mysql數據庫查詢商品信息。
⒉ jar包
包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、數據庫驅動、第三方連接池。
參考:“mybatis與springmvc整合全部jar包”目錄 
⒊ 工程搭建
⑴ 整合思路
Dao層:
① SqlMapConfig.xml,空文件即可。需要文件頭。
② applicationContext-dao.xml。
a)    數據庫連接池。
b)    SqlSessionFactory對象,需要spring和mybatis整合包下的。
c)    配置mapper文件掃描器。
Service層:
① applicationContext-service.xml包掃描器,掃描@service註解的類。
② applicationContext-trans.xml配置事務。
表現層:
Springmvc.xml
① 包掃描器,掃描@Controller註解的類。
② 配置註解驅動。
③視圖解析器:Web.xml,配置前端控制器。
⑵ sqlMapConfig.xml
在classpath下創建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>

⑶ 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>
	<!-- mapper配置 -->
	<!-- 讓spring管理sqlsessionfactory 使用mybatis和spring整合包中的 -->
	<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">
		<property name="basePackage" value="cn.itcast.springmvc.mapper"/>
	</bean>

</beans>

Db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

⑷ 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">

	<context:component-scan base-package="cn.itcast.springmvc.service"/>

</beans>

⑸ applicationContext-transaction.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:attributes>
	</tx:advice>
	<!-- 切面 -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice"
			pointcut="execution(* cn.itcast.springmvc.service.*.*(..))" />
	</aop:config>
</beans>

⑹ 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:dubbo="http://code.alibabatech.com/schema/dubbo" 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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.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" />
	<!-- 加載註解驅動 -->
	<mvc:annotation-driven/>
	<!-- 視圖解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<!-- jsp前綴 -->
		<property name="prefix" value="/WEB-INF/jsp/" />
		<!-- jsp後綴 -->
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

⑺ 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>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<servlet>
		<servlet-name>springmvc</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</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
</web-app>

⒋ Dao
mybatis逆向工程。

⒌ Service
Service由spring管理 、spring對Service進行事務控制。
⑴ ItemService接口

public interface ItemService {

	List<Items> getItemsList();
}

⑵ ItemServiceImpl實現類

@Service
public class ItemServiceImpl implements ItemService {

	@Autowired
	private ItemMapper itemMapper;
	
	@Override
	public List<Items> getItemsList() {
		List<Items> itemList = itemMapper.getItemList();
		return itemList;
	}

}

⑶ Controller

@Controller
public class ItemController {

	@Autowired
	private ItemService itemService;
	
	@RequestMapping("/itemList")
	public ModelAndView getItemList() {
		List<Items> list = itemService.getItemsList();
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemList", list);
		modelAndView.setViewName("itemList");
		return modelAndView;
	}
}

⑷ 測試,訪問:http://localhost:8080/springmvc-web/itemList.action


參數綁定

⒈ 綁定簡單數據類型
⑴ 需求:打開商品編輯頁面,展示商品信息。
⑵ 需求分析
編輯商品信息,需要根據商品id查詢商品信息,然後展示到頁面;
請求的url:/itemEdit.action;
參數:id(商品id)。
響應結果:商品編輯頁面,展示商品詳細信息。

⑶ service

@Override
	public Items getItemById(int id) {
		Items items = itemMapper.getItemById(id);
		return items;
	}

⑷ Controller參數綁定
要根據id查詢商品數據,需要從請求的參數中把請求的id取出來。Id應該包含在Request對象中。可以從Request對象中取id。

@RequestMapping("/itemEdit")
	public ModelAndView itemEdit(HttpServletRequest request) {
		//從Request中取id
		String strId = request.getParameter("id");
		Integer id = null;
		//如果id有值則轉換成int類型
		if (strId != null && !"".equals(strId)) {
			id = new Integer(strId);
		} else {
			//出錯
			return null;
		}
		Items items = itemService.getItemById(id);
		//創建ModelAndView
		ModelAndView modelAndView = new ModelAndView();
		//向jsp傳遞數據
		modelAndView.addObject("item", items);
		//設置跳轉的jsp頁面
		modelAndView.setViewName("editItem");
		return modelAndView;
	}

如果想獲得Request對象只需要在Controller方法的形參中添加一個參數即可。Springmvc框架會自動把Request對象傳遞給方法。
⑸ 默認支持的參數類型
處理器形參中添加如下類型的參數處理適配器會默認識別並進行賦值。
① HttpServletRequest:通過request對象獲取請求信息。
② HttpServletResponse:通過response處理響應信息。
③ HttpSession:通過session對象得到session中存放的對象。
④ Model/ModelMap
ModelMap是Model接口的實現類,通過Model或ModelMap向頁面傳遞數據,如下:
//調用service查詢商品信息

Items item = itemService.findItemById(id);
model.addAttribute("item", item);

頁面通過${item.XXXX}獲取item對象的屬性值。
使用Model和ModelMap的效果一樣,如果直接使用Model,springmvc會實例化ModelMap。
如果使用Model則可以不使用ModelAndView對象,Model對象可以向頁面傳遞數據,View對象則可以使用String返回值替代。不管是Model還是ModelAndView,其本質都是使用Request對象向jsp傳遞數據。
如果使用Model則方法可以改造成:

@RequestMapping("/itemEdit")
	public String itemEdit(HttpServletRequest request, Model model) {
		//從Request中取id
		String strId = request.getParameter("id");
		Integer id = null;
		//如果id有值則轉換成int類型
		if (strId != null && !"".equals(strId)) {
			id = new Integer(strId);
		} else {
			//出錯
			return null;
		}
		Items items = itemService.getItemById(id);
		//創建ModelAndView
		//ModelAndView modelAndView = new ModelAndView();
		//向jsp傳遞數據
		//modelAndView.addObject("item", items);
		model.addAttribute("item", items);
		//設置跳轉的jsp頁面
		//modelAndView.setViewName("editItem");
		//return modelAndView;
		return "editItem";
	}

⑹ 綁定簡單類型
當請求的參數名稱和處理器形參名稱一致時會將請求參數與形參進行綁定。從Request取參數的方法可以進一步簡化。

@RequestMapping("/itemEdit")
	public String itemEdit(Integer id, Model model) {
		Items items = itemService.getItemById(id);
		//向jsp傳遞數據
		model.addAttribute("item", items);
		//設置跳轉的jsp頁面
		return "editItem";
	}

① 支持的數據類型
參數類型推薦使用包裝數據類型,因爲基礎數據類型不可以爲null
整形:Integer、int
字符串:String
單精度:Float、float
雙精度:Double、double
布爾型:Boolean、boolean
說明:對於布爾類型的參數,請求的參數值爲true或false。
處理器方法:
public String editItem(Model model,Integer id,Boolean status) throws Exception
請求url:
http://localhost:8080/xxx.action?id=abc&status=false
② @RequestParam 
使用@RequestParam常用於處理簡單類型的綁定。
value:參數名字,即入參的請求參數名字,如value=“item_id”表示請求的參數區中的名字爲item_id的參數的值將傳入;
required:是否必須,默認是true,表示請求中一定要有相應的參數,否則將報;
TTP Status 400 - Required Integer parameter 'XXXX' is not present;
defaultValue:默認值,表示如果請求中沒有同名參數時的默認值;
定義如下:

public String editItem(@RequestParam(value="item_id",required=true) String id) {
	
}

形參名稱爲id,但是這裏使用value=" item_id"限定請求的參數名爲item_id,所以頁面傳遞參數的名必須爲item_id。
注意:如果請求參數中沒有item_id將跑出異常:
HTTP Status 500 - Required Integer parameter 'item_id' is not present
這裏通過required=true限定item_id參數爲必需傳遞,如果不傳遞則報400錯誤,可以使用defaultvalue設置默認值,即使required=true也可以不傳item_id參數值。

⒉ 綁定pojo類型
⑴ 需求:將頁面修改後的商品信息保存到數據庫中。
⑵ 需求分析
請求的url:/updateitem.action;
參數:表單中的數據;
響應內容:更新成功頁面。
⑶ 使用pojo接收表單數據
如果提交的參數很多,或者提交的表單中的內容很多的時候可以使用pojo接收數據。要求pojo對象中的屬性名和表單中input的name屬性一致。
頁面定義如下;

<input type="text" name="name"/>
<input type="text" name="price"/>

Pojo定義:


請求的參數名稱和pojo的屬性名稱一致,會自動將請求參數賦值給pojo的屬性。

@RequestMapping("/updateitem")
	public String updateItem(Items items) {
		itemService.updateItem(items);
		return "success";
	}

注意:提交的表單中不要有日期類型的數據,否則會報400錯誤。如果想提交日期類型的數據需要用到後面的自定義參數綁定的內容。
⑷ 解決post亂碼問題
在web.xml中加入:

<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</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編碼

⒊ 綁定包裝pojo
⑴ 需求:使用包裝的pojo接收商品信息的查詢條件。
⑵ 需求分析
包裝對象定義如下:

Public class QueryVo {
private Items items;

}

頁面定義:

<input type="text" name="items.name" />
<input type="text" name="items.price" />

Controller方法定義如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
System.out.println(queryVo.getItems());

⑶ 接收查詢條件

@RequestMapping("/queryitem")
	public String queryItem(QueryVo queryVo) {
		System.out.println(queryVo.getItems().getName());
		System.out.println(queryVo.getItems().getPrice());
		return null;
	}

⒋ 自定義參數綁定
⑴ 需求:在商品修改頁面可以修改商品的生產日期,並且根據業務需求自定義日期格式。
⑵ 需求分析
    由於日期數據有很多種格式,所以springmvc沒辦法把字符串轉換成日期類型。所以需要自定義參數綁定。前端控制器接收到請求後,找到註解形式的處理器適配器,對RequestMapping標記的方法進行適配,並對方法中的形參進行參數綁定。在springmvc這可以在處理器適配器上自定義Converter進行參數綁定。如果使用<mvc:annotation-driven/>可以在此標籤上進行擴展。
⑶ 自定義Converter

public class DateConverter implements Converter<String, Date> {

	@Override
	public Date convert(String source) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return simpleDateFormat.parse(source);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
}

⑷ 配置Converter

	<!-- 加載註解驅動 -->
	<mvc:annotation-driven conversion-service="conversionService"/>
	<!-- 轉換器配置 -->
	<bean id="conversionService"
		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<property name="converters">
			<set>
				<bean class="cn.itcast.springmvc.convert.DateConverter"/>
			</set>
		</property>
	</bean>

⑸ 配置方式2(瞭解)

<?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:dubbo="http://code.alibabatech.com/schema/dubbo" 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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.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" />
	
	<!-- 轉換器配置 -->
	<bean id="conversionService"
		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<property name="converters">
			<set>
				<bean class="cn.itcast.springmvc.convert.DateConverter"/>
			</set>
		</property>
	</bean>
	<!-- 自定義webBinder -->
	<bean id="customBinder"	class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
		<property name="conversionService" ref="conversionService" />
	</bean>
	<!--註解適配器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		 <property name="webBindingInitializer" ref="customBinder"></property> 
	</bean>
	<!-- 註解處理器映射器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
	<!-- 加載註解驅動 -->
	<!-- <mvc:annotation-driven/> -->
	<!-- 視圖解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<!-- jsp前綴 -->
		<property name="prefix" value="/WEB-INF/jsp/" />
		<!-- jsp後綴 -->
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

注意:此方法需要獨立配置處理器映射器、適配器,不再使用<mvc:annotation-driven/>


springmvc與struts2不同

⒈ springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過慮器。
⒉ springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,可以設計爲單例或多例(建議單例),struts2是基於類開發,傳遞參數是通過類的屬性,只能設計爲多例。
⒊ Struts採用值棧存儲請求和響應的數據,通過OGNL存取數據, springmvc通過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最後又將ModelAndView中的模型數據通過request域傳輸到頁面。Jsp視圖解析器默認使用jstl。


高級參數綁定

⒈ 綁定數組
⑴ 需求:在商品列表頁面選中多個商品,然後刪除。
⑵ 需求分析
此功能要求商品列表頁面中的每個商品前有一個checkbook,選中多個商品後點擊刪除按鈕把商品id傳遞給Controller,根據商品id刪除商品信息。
⑶ Jsp中實現:

<c:forEach items="${itemList }" var="item">
<tr>
	<td><input name="ids" value="${item.id}" type="checkbox"></td>
	<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 }/itemEdit.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>

生成html代碼如下:頁面選中多個checkbox向controller方法傳遞。

<table width="100%" border=1>
<tr>
	<td>商品名稱</td>
	<td>商品價格</td>
	<td>生產日期</td>
	<td>商品描述</td>
	<td>操作</td>
</tr>
<tr>
	<td><input name="ids" value="1" type="checkbox"></td>
	<td>臺式機</td>
	<td>3000.0</td>
	<td>2016-02-03 13:22:53</td>
	<td></td>
	<td><a href="/springmvc-web/itemEdit.action?id=1">修改</a></td>
</tr>
<tr>
	<td><input name="ids" value="2" type="checkbox"></td>
	<td>筆記本</td>
	<td>6000.0</td>
	<td>2015-02-09 13:22:57</td>
	<td></td>
	<td><a href="/springmvc-web/itemEdit.action?id=2">修改</a></td>
</tr>
<tr>
	<td><input name="ids" value="3" type="checkbox"></td>
	<td>揹包</td>
	<td>200.0</td>
	<td>2015-02-06 13:23:02</td>
	<td></td>
	<td><a href="/springmvc-web/itemEdit.action?id=3">修改</a></td>
</tr>
</table>

⑷ Controller
Controller方法中可以用String[]接收,或者pojo的String[]屬性接收。兩種方式任選其一即可。
定義如下:

@RequestMapping("/queryitem")
	public String queryItem(QueryVo queryVo, String[] ids) {
		System.out.println(queryVo.getItems().getName());
		System.out.println(queryVo.getItems().getPrice());
		System.out.println(ids.toString());
		return null;
	}

或者:


查看結果:


⒉ 將表單的數據綁定到List
⑴ 需求:實現商品數據的批量修改。
⑵ 需求分析:要想實現商品數據的批量修改,需要在商品列表中可以對商品信息進行修改,並且可以批量提交修改後的商品數據。
⑶ 接收商品列表的pojo


List中存放對象,並將定義的List放在包裝類中,使用包裝pojo對象接收。
⑷ Jsp改造
頁面定義如下:


<tr>
<td>
<input type="text" name="name" value="123"/>
</td>
<td>
<input type="text" name="name" value="12311"/>
</td>
<td>
<input type="text" name=" itemsList[0].price" value="${item.price}"/>
</td>
</tr>
<tr>
<td>
<input type="text" name=" itemsList[1].id" value="${item.id}"/>
</td>
<td>
<input type="text" name=" itemsList[1].name" value="${item.name }"/>
</td>
<td>
<input type="text" name=" itemsList[1].price" value="${item.price}"/>
</td>
</tr>

Name屬性必須是包裝pojo的list屬性+下標+元素屬性。Jsp做如下改造:

<c:forEach items="${itemList }" var="item">
<tr>
	<td><input name="ids" value="${item.id}" type="checkbox"></td>
	<td>
		<input name="id" value="${item.id}" type="hidden">
		<input name="name" value="${item.name }" type="text">
	</td>
	<td><input name="name" value="${item.price }" type="text"></td>
	<td><input name="name" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" type="text"></td>
	<td><input name="name" value="${item.detail }" type="text"></td>
	<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>

varStatus屬性常用參數總結下:
${status.index}      輸出行號,從0開始。
${status.count}      輸出行號,從1開始。
${status.current}   當前這次迭代的(集合中的)項
${status.first}  判斷當前項是否爲集合中的第一項,返回值爲true或false
${status.last}   判斷當前項是否爲集合中的最後一項,返回值爲true或false
begin、end、step分別表示:起始序號,結束序號,跳躍步伐。

⑸ Contrller

@RequestMapping("/queryitem")
	public String queryItem(QueryVo queryVo, String[] ids) {
		System.out.println(queryVo.getItems().getName());
		System.out.println(queryVo.getItems().getPrice());
		System.out.println(ids.toString());
		return null;
	}

注意:接收List類型的數據必須是pojo的屬性,方法的形參爲List類型無法正確接收到數據。


@RequestMapping

通過RequestMapping註解可以定義不同的處理器映射規則。
⒈ URL路徑映射
@RequestMapping(value="/item")或@RequestMapping("/item)
value的值是數組,可以將多個url映射到同一個方法
⒉ 窄化請求映射
在class上添加@RequestMapping(url)指定通用請求前綴, 限制此類下的所有方法請求url必須以請求前綴開頭,通過此方法對url進行分類管理。
如下:
@RequestMapping放在類名上邊,設置請求前綴 
@Controller
@RequestMapping("/item")
方法名上邊設置請求映射url:
@RequestMapping放在方法名上邊,如下:
@RequestMapping("/queryItem ")
訪問地址爲:/item/queryItem
 ⒊ 請求方法限定 
    限定GET方法
@RequestMapping(method = RequestMethod.GET)
如果通過Post訪問則報錯:
HTTP Status 405 - Request method 'POST' not supported
例如:
@RequestMapping(value="/editItem",method=RequestMethod.GET)
    限定POST方法
@RequestMapping(method = RequestMethod.POST)
如果通過Post訪問則報錯:
HTTP Status 405 - Request method 'GET' not supported
    GET和POST都可以
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})


controller方法返回值

⒈ 返回ModelAndView
controller方法中定義ModelAndView對象並返回,對象中可添加model數據、指定view。
⒉ 返回void
    在controller方法形參上可以定義request和response,使用request或response指定響應結果:
⑴ 使用request轉向頁面,如下:
request.getRequestDispatcher("頁面路徑").forward(request, response);
⑵ 也可以通過response頁面重定向:
response.sendRedirect("url")
⑶ 也可以通過response指定響應結果,例如響應json數據如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
⒊ 返回字符串
⑴ 邏輯視圖名
controller方法返回字符串可以指定邏輯視圖名,通過視圖解析器解析爲物理視圖地址。
//指定邏輯視圖名,經過視圖解析器解析爲jsp物理路徑:/WEB-INF/jsp/item/editItem.jsp
return "item/editItem";
⑵ Redirect重定向
Contrller方法返回結果重定向到一個url地址,如下商品修改提交後重定向到商品查詢方法,參數無法帶到商品查詢方法中。
//重定向到queryItem.action地址,request無法帶過去
return "redirect:queryItem.action";
redirect方式相當於“response.sendRedirect()”,轉發後瀏覽器的地址欄變爲轉發後的地址,因爲轉發即執行了一個新的request和response。
由於新發起一個request原來的參數在轉發時就不能傳遞到下一個url,如果要傳參數可以/item/queryItem.action後邊加參數,如下:
/item/queryItem?...&…..
⑶ forward轉發
controller方法執行後繼續執行另一個controller方法,如下商品修改提交後轉向到商品修改頁面,修改商品的id參數可以帶到商品修改方法中。
//結果轉發到editItem.action,request可以帶過去
return "forward:editItem.action";
forward方式相當於“request.getRequestDispatcher().forward(request,response)”,轉發後瀏覽器地址欄還是原來的地址。轉發並沒有執行新的request和response,而是和轉發前的請求共用一個request和response。所以轉發前請求的參數在轉發後仍然可以讀取到。


異常處理器

springmvc在處理請求過程中出現異常信息交由異常處理器進行處理,自定義異常處理器可以實現一個系統的異常處理邏輯。    
⒈ 異常處理思路
    系統中異常包括兩類:預期異常和運行時異常RuntimeException,前者通過捕獲異常從而獲取異常信息,後者主要通過規範代碼開發、測試通過手段減少運行時異常的發生。
    系統的dao、service、controller出現都通過throws Exception向上拋出,最後由springmvc前端控制器交由異常處理器進行異常處理,如下圖:


⒉ 自定義異常類
    爲了區別不同的異常通常根據異常類型自定義異常類,這裏我們創建一個自定義系統異常,如果controller、service、dao拋出此類異常說明是系統預期處理的異常信息。

public class CustomException extends Exception {

	/** serialVersionUID*/
	private static final long serialVersionUID = -5212079010855161498L;
	
	public CustomException(String message){
		super(message);
		this.message = message;
	}

	//異常信息
	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

⒊ 自定義異常處理器

public class CustomExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {

		ex.printStackTrace();

		CustomException customException = null;
		
		//如果拋出的是系統自定義異常則直接轉換
		if(ex instanceof CustomException){
			customException = (CustomException)ex;
            customException.getMessage()
		}else{
			//如果拋出的不是系統自定義異常則重新構造一個系統錯誤異常。
			customException = new CustomException("系統錯誤,請與系統管理 員聯繫!");
		}
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message", customException.getMessage());
		modelAndView.setViewName("error");

		return modelAndView;
	}

}
取異常堆棧:
           try {
			
		} catch (Exception e) {
			StringWriter s = new StringWriter();
			PrintWriter printWriter = new PrintWriter(s);
			e.printStackTrace(printWriter);
			s.toString();
		}

⒋ 錯誤頁面

<%@ 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>
您的操作出現錯誤如下:<br/>
${message }
</body>

</html>

⒌ 異常處理器配置
在springmvc.xml中添加:

<!-- 異常處理器 -->
	<bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/>

⒍ 異常測試
修改商品信息,id輸入錯誤提示商品信息不存在。
修改controller方法“editItem”,調用service查詢商品信息,如果商品信息爲空則拋出異常:

/ 調用service查詢商品信息
		Items item = itemService.findItemById(id);
		
		if(item == null){
			throw new CustomException("商品信息不存在!");
		}

在service中拋出異常方法同上。


上傳圖片

⒈ 配置虛擬目錄 
在tomcat上配置圖片虛擬目錄,在tomcat下conf/server.xml中添加:
<Context docBase="F:\develop\upload\temp" path="/pic" reloadable="false"/>
訪問http://localhost:8080/pic即可訪問F:\develop\upload\temp下的圖片。
也可以通過eclipse配置:


⒉ jar包
CommonsMultipartResolver解析器依賴commons-fileupload和commons-io,加入如下jar包:


⒊ 配置解析器

<!-- 文件上傳 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 設置上傳文件的最大尺寸爲5MB -->
		<property name="maxUploadSize">
			<value>5242880</value>
		</property>
	</bean>

⒋ 圖片上傳
⑴ controller:

//商品修改提交
	@RequestMapping("/editItemSubmit")
	public String editItemSubmit(Items items, MultipartFile pictureFile)throws Exception{
		
		//原始文件名稱
		String pictureFile_name =  pictureFile.getOriginalFilename();
		//新文件名稱
		String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));
		
		//上傳圖片
		File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);
		
		if(!uploadPic.exists()){
			uploadPic.mkdirs();
		}
		//向磁盤寫文件
		pictureFile.transferTo(uploadPic);

.....

⑵ 頁面:form添加enctype="multipart/form-data":

<form id="itemForm"
action="${pageContext.request.contextPath }/item/editItemSubmit.action"
		method="post" enctype="multipart/form-data">
		<input type="hidden" name="pic" value="${item.pic }" />

file的name與controller形參一致:

<tr>
	<td>商品圖片</td>
	<td><c:if test="${item.pic !=null}">
			<input type=”hidden” name=”pic” value=” ${item.pic}”/>
			<img src="/pic/${item.pic}" width=100 height=100 />
			<br />
		</c:if> 
<input type="file" name="picture" /></td>
</tr>

 json數據交互

⒈ @RequestBody
作用:
@RequestBody註解用於讀取http請求的內容(字符串),通過springmvc提供的HttpMessageConverter接口將讀到的內容轉換爲json、xml等格式的數據並綁定到controller方法的參數上。
List.action?id=1&name=zhangsan&age=12
本例子應用:
@RequestBody註解實現接收http請求的json數據,將json數據轉換爲java對象
⒉ @ResponseBody
作用:
該註解用於將Controller的方法返回的對象,通過HttpMessageConverter接口轉換爲指定格式的數據如:json,xml等,通過Response響應給客戶端
本例子應用:@ResponseBody註解實現將controller方法返回對象轉換爲json響應給客戶端
⒊ 請求json,響應json實現:
⑴ 環境準備
Springmvc默認用MappingJacksonHttpMessageConverter對json數據進行轉換,需要加入jackson的包,如下:


⑵ 配置json轉換器
在註解適配器中加入messageConverters

<!--註解適配器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="messageConverters">
		<list>
		<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
		</list>
		</property>
	</bean>

注意:如果使用<mvc:annotation-driven /> 則不用定義上邊的內容。
⑶ controller編寫

// 商品修改提交json信息,響應json信息
	@RequestMapping("/editItemSubmit_RequestJson")
	public @ResponseBody Items editItemSubmit_RequestJson(@RequestBody Items items) throws Exception {
		System.out.println(items);
		//itemService.saveItem(items);
		return items;
	}

⑷ 頁面js方法編寫:
引入 js:
<script type="text/javascript" 
src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>

//請求json響應json
	function request_json(){
		$.ajax({
			type:"post",
			url:"${pageContext.request.contextPath }/item/editItemSubmit_RequestJson.action",
			contentType:"application/json;charset=utf-8",
			data:'{"name":"測試商品","price":99.9}',
			success:function(data){
				alert(data);
			}
		});
	}

⑸ 測試結果:


從上圖可以看出請求的數據是json格式


RESTful支持

⒈  什麼是restful?
Restful就是一個資源定位及資源操作的風格。不是標準也不是協議,只是一種風格,是對http協議的詮釋。
資源定位:互聯網所有的事物都是資源,要求url中沒有動詞,只有名詞。沒有參數
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
資源操作:使用put、delete、post、get,使用不同方法對資源進行操作。分別對應添加、刪除、修改、查詢。一般使用時還是post和get。Put和Delete幾乎不使用。
⒉ 需求:RESTful方式實現商品信息查詢,返回json數據。
⒊ 添加DispatcherServlet的rest配置

<servlet>
		<servlet-name>springmvc-servlet-rest</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-servlet-rest</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

⒋ URL 模板模式映射
@RequestMapping(value="/ viewItems/{id}"):{×××}佔位符,請求的URL可以是“/viewItems/1”或“/viewItems/2”,通過在方法中使用@PathVariable獲取{×××}中的×××變量。
@PathVariable用於將請求URL中的模板變量映射到功能處理方法的參數上。
/asdfasdf/xxx
/{aa}/xxx
@PathVariable String aa
aa= “asdfasdf”;

@RequestMapping("/viewItems/{id}") 
	public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
		//方法中使用@PathVariable獲取useried的值,使用model傳回頁面
		//調用 service查詢商品信息
		ItemsCustom itemsCustom = itemsService.findItemsById(id);
		return itemsCustom;
}

如果RequestMapping中表示爲"/viewItems/{id}",id和形參名稱一致,@PathVariable不用指定名稱。
商品查詢的controller方法也改爲rest實現:

// 查詢商品列表
	@RequestMapping("/queryItem")
	public ModelAndView queryItem() throws Exception {
		// 商品列表
		List<Items> itemsList = itemService.findItemsList(null);

		// 創建modelAndView準備填充數據、設置視圖
		ModelAndView modelAndView = new ModelAndView();

		// 填充數據
		modelAndView.addObject("itemsList", itemsList);
		// 視圖
		modelAndView.setViewName("item/itemsList");

		return modelAndView;
	}

⒌ 靜態資源訪問<mvc:resources>
如果在DispatcherServlet中設置url-pattern爲 /則必須對靜態資源進行訪問處理。
spring mvc 的<mvc:resources mapping="" location="">實現對靜態資源進行映射訪問。
如下是對js文件訪問配置:
<mvc:resources location="/js/" mapping="/js/**"/>


 攔截器

⒈ 定義
    Spring Web MVC 的處理器攔截器類似於Servlet 開發中的過濾器Filter,用於對處理器進行預處理和後處理。
⒉ 攔截器定義
實現HandlerInterceptor接口,如下:

Public class HandlerInterceptor1 implements HandlerInterceptor{

	/**
	 * controller執行前調用此方法
	 * 返回true表示繼續執行,返回false中止執行
	 * 這裏可以加入登錄校驗、權限攔截等
	 */
	@Override
	Public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
		Return false;
	}
	/**
	 * controller執行後但未返回視圖前調用此方法
	 * 這裏可在返回用戶前對模型數據進行加工處理,比如這裏加入公用信息以便頁面顯示
	 */
	@Override
	Public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		
	}
	/**
	 * controller執行後且視圖返回後調用此方法
	 * 這裏可得到執行controller時的異常信息
	 * 這裏可記錄操作日誌,資源清理等
	 */
	@Override
	Public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		
	}

}

⒊ 攔截器配置
⑴ 針對某種mapping配置攔截器

<bean
	class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
	<property name="interceptors">
		<list>
			<ref bean="handlerInterceptor1"/>
			<ref bean="handlerInterceptor2"/>
		</list>
	</property>
</bean>
	<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
	<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

⑵ 針對所有mapping配置全局攔截器

<!--攔截器 -->
<mvc:interceptors>
	<!--多個攔截器,順序執行 -->
	<mvc:interceptor>
		<mvc:mapping path="/**"/>
		<bean class="cn.itcast.springmvc.filter.HandlerInterceptor1"></bean>
	</mvc:interceptor>
	<mvc:interceptor>
		<mvc:mapping path="/**"/>
		<bean class="cn.itcast.springmvc.filter.HandlerInterceptor2"></bean>
	</mvc:interceptor>
</mvc:interceptors>

⒋ 正常流程測試
⑴ 代碼:
定義兩個攔截器分別爲:HandlerInterceptor1和HandlerInteptor2,每個攔截器的preHandler方法都返回true。


⑵ 運行流程

HandlerInterceptor1..preHandle..
HandlerInterceptor2..preHandle..
HandlerInterceptor2..postHandle..
HandlerInterceptor1..postHandle..
HandlerInterceptor2..afterCompletion..
HandlerInterceptor1..afterCompletion..
⒌ 中斷流程測試
⑴ 代碼:
定義兩個攔截器分別爲:HandlerInterceptor1和HandlerInteptor2。
⑵ 運行流程
HandlerInterceptor1的preHandler方法返回false,HandlerInterceptor2返回true,運行流程如下:
HandlerInterceptor1..preHandle..
從日誌看出第一個攔截器的preHandler方法返回false後第一個攔截器只執行了preHandler方法,其它兩個方法沒有執行,第二個攔截器的所有方法不執行,且controller也不執行了。
HandlerInterceptor1的preHandler方法返回true,HandlerInterceptor2返回false,運行流程如下:
HandlerInterceptor1..preHandle..
HandlerInterceptor2..preHandle..
HandlerInterceptor1..afterCompletion..
從日誌看出第二個攔截器的preHandler方法返回false後第一個攔截器的postHandler沒有執行,第二個攔截器的postHandler和afterCompletion沒有執行,且controller也不執行了。
總結:
preHandle按攔截器定義順序調用
postHandler按攔截器定義逆序調用
afterCompletion按攔截器定義逆序調用
postHandler在攔截器鏈內所有攔截器返成功調用
afterCompletion只有preHandle返回true才調用
⒍ 攔截器應用
⑴ 處理流程
① 有一個登錄頁面,需要寫一個controller訪問頁面;
② 登錄頁面有一提交表單的動作。需要在controller中處理。
a)    判斷用戶名密碼是否正確;
b)    如果正確 想session中寫入用戶信息;
c)    返回登錄成功,或者跳轉到商品列表。
③ 攔截器。
a)    攔截用戶請求,判斷用戶是否登錄;
b)    如果用戶已經登錄。放行;
c)    如果用戶未登錄,跳轉到登錄頁面。
⑵ 用戶身份認證

Public class LoginInterceptor implements HandlerInterceptor{

	@Override
	Public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {

		//如果是登錄頁面則放行
		if(request.getRequestURI().indexOf("login.action")>=0){
			return true;
		}
		HttpSession session = request.getSession();
		//如果用戶已登錄也放行
		if(session.getAttribute("user")!=null){
			return true;
		}
		//用戶沒有登錄挑戰到登錄頁面
		request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
		
		return false;
	}
}

⑶ 用戶登陸controller

//登陸頁面
	@RequestMapping("/login")
	public String login(Model model)throws Exception{
		
		return "login";
	}
	
	//登陸提交
	//userid:用戶賬號,pwd:密碼
	@RequestMapping("/loginsubmit")
	public String loginsubmit(HttpSession session,String userid,String pwd)throws Exception{
		
		//向session記錄用戶身份信息
		session.setAttribute("activeUser", userid);
		
		return "redirect:item/queryItem.action";
	}
	
	//退出
	@RequestMapping("/logout")
	public String logout(HttpSession session)throws Exception{
		
		//session過期
		session.invalidate();
		
		return "redirect:item/queryItem.action";
	}

Mybatis、Springmvc練習CRM系統


⒈ 數據庫
數據庫使用mysql 數據庫。


① 創建crm數據庫
② 將參考資料中的sql腳本導入到數據庫中
⒉ 工程搭建
工程使用Springmvc、spring、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>

⑵ applicationContext-dao.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"
	xmlns:task="http://www.springframework.org/schema/task" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	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 
		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/task
   		http://www.springframework.org/schema/task/spring-task-4.0.xsd
		http://code.alibabatech.com/schema/dubbo        
		http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

	<!-- 配置 讀取properties文件 jdbc.properties -->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 配置 數據源 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<!-- 驅動 -->
		<property name="driverClassName" value="${jdbc.driver}" />
		<!-- url -->
		<property name="url" value="${jdbc.url}" />
		<!-- 用戶名 -->
		<property name="username" value="${jdbc.username}" />
		<!-- 密碼 -->
		<property name="password" value="${jdbc.password}" />
	</bean>

	<!-- 配置 Mybatis的工廠 -->
	<bean class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 數據源 -->
		<property name="dataSource" ref="dataSource" />
		<!-- 配置Mybatis的核心 配置文件所在位置 -->
		<property name="configLocation" value="classpath:SqlMapConfig.xml" />
		<!-- 配置pojo別名 -->
		<property name="typeAliasesPackage" value="cn.itcast.core.bean"></property>
	</bean>

	<!-- 配置 1:原始Dao開發 接口實現類 Mapper.xml 三個 2:接口開發 接口 不寫實現類 Mapper.xml 二個 (UserDao、ProductDao 
		、BrandDao。。。。。。。) 3:接口開發、並支持掃描 cn.itcast.core.dao(UserDao。。。。。) 寫在此包下即可被掃描到 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="cn.itcast.core.dao" />
	</bean>

</beans>

Jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/crm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

⑶ applicationContext-service.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"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	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 
		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/task
   		http://www.springframework.org/schema/task/spring-task-4.0.xsd
		http://code.alibabatech.com/schema/dubbo        
		http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
		
		<!-- 配置  掃描   @Service -->
		<context:component-scan base-package="cn.itcast.core.service"/>		
		
</beans>

⑷ 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="add*" propagation="REQUIRED" />
			<tx:method name="create*" 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="select*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<!-- 切面 -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice"
			pointcut="execution(* cn.itcast.core.service.*.*(..))" />
	</aop:config>
</beans>

⑸ Springmvc.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"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	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 
		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/task
   		http://www.springframework.org/schema/task/spring-task-4.0.xsd
		http://code.alibabatech.com/schema/dubbo        
		http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
		
		<!-- 加載屬性文件 -->
		<context:property-placeholder location="classpath:resource.properties"/>
		<!-- 配置掃描 器 -->
		<context:component-scan base-package="cn.itcast.core.web.controller"/>
		<!-- 配置處理器映射器  適配器 -->
		<mvc:annotation-driven/>
		
		<!-- 配置視圖解釋器 jsp -->
		<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
			<property name="prefix" value="/WEB-INF/jsp/"/>
			<property name="suffix" value=".jsp"/>
		</bean>
		
</beans>

⑹ Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<welcome-file-list>
		<welcome-file>customer.action</welcome-file>
	</welcome-file-list>
	<!-- 上下文的位置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext-*.xml</param-value>
	</context-param>
	<!-- Spring的監聽器 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>


	<!-- POST提交過濾器 UTF-8 -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<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>*.action</url-pattern>
	</filter-mapping>
	<!-- 前端控制器 -->
	<servlet>
		<servlet-name>crm</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<!-- 此處不配置 默認找 /WEB-INF/[servlet-name]-servlet.xml -->
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>crm</servlet-name>
		<!-- 1:*.do *.action 攔截以.do結尾的請求 (不攔截 jsp png jpg .js .css) 2:/ 攔截所有請求 
			(不攔截.jsp) 建議使用此種 方式 (攔截 .js.css .png) (放行靜態資源) 3:/* 攔截所有請求(包括.jsp) 此種方式 不建議使用 -->
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
</web-app>

⑺ 加入jsp及分頁標籤


⒊ 查詢條件初始化
需求:初始化查詢條件下拉列表。


⒋客戶列表展示
需求分析

展示商品列表,並且可以根據查詢條件過濾查詢結果,並且實現分頁處理。
自定義查詢Pojo:


⒌修改客戶信息
需求

① 點擊客戶列表中的“修改”按鈕彈出客戶信息修改對話框,並初始化客戶信息;② 點擊“保存修改”按鈕將修改後的結果保存到數據庫中。
⒍ 刪除客戶
需求

點擊客戶列表中的刪除按鈕,提示“警告信息”。

點擊確定後刪除用戶信息,並刷新頁面。

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章