spring MVC框架
一、什么是spring MVC
Spring MVC屬於SpringFrameWork的后續產品,已經融合在Spring Web Flow里面。Spring 框架提供了構建 Web 應用程序的全功能 MVC 模塊。使用 Spring 可插入的 MVC 架構,從而在使用Spring進行WEB開發時,可以選擇使用Spring的SpringMVC框架或集成其他MVC開發框架,如Struts1(現在一般不用),Struts2等。
---------百度百科
從spring官網中可以看出,Spring MVC原名叫Spring Web MVC,它是構建在Servlet API上的最初的Web框架,從一開始就包含在Spring框架中。正式名稱“Spring Web MVC”來自其源模塊spring-webmvc的名稱, 但它通常被稱為“Spring MVC”。Spring web mvc和Struts2都屬於表現層的框架,它是Spring框架的一部分。
二、spring MVC框架的作用
從請求中接收傳入的參數,將處理后的結果返回給頁面展示
三、spring MVC執行流程

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響應用戶
四、快速開發
需求:顯示商品列表
1、導入所需基本依賴jar包
jar包下載地址:springMVC_jar

如果是maven。其相關依賴為
<dependencies>
<dependency>
<!--使用Junit4,采用注解形式 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--數據庫驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<!--配置maven工作范圍:因為驅動只有真正工作時才會啟動 -->
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<!--spring依賴 -->
<!--1.spring核心依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--2.spring Dao層依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--3.spring web相關依賴:用於當啟動服務器時加載配置文件 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--用於springMVC需要 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--4.spring test測試相關依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
</dependencies>
2、在項目工程上創建源碼包,用來存放配置文件
3、創建spring MVC核心配置文件,文件名就叫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"> </beans>
4、創建日志文件,用於打印日志(log4j.properties)
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
5、定義Controller類
ItemController是一個普通的java類,不需要實現任何接口,只需要在類上添加@Controller注解即可。@RequestMapping注解指定請求的url,其中“.action”可以加 也可以不加。注意:1.這里的配置@Controller注解 2.@RequestMapping用於識別域名后綴 3.modelAndView.setViewName用於設置跳轉頁面
// 在添加注解的同時,還得配置掃描 @Controller public class ItemsController { //指定url到請求方法的映射 //url中輸入一個地址,例如:localhost:8888/SpringMvc/list.action //用以替代了struts中采用的配置文件進行匹配來調用那個方法從而識別跳轉那個頁面 @RequestMapping("/list") public ModelAndView itemsList()throws Exception{ List<Items> itemList = new ArrayList<Items>(); //商品列表 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); //模型視圖 //model模型:模型對象中存放了返回給頁面的數據 //view視圖:視圖對象中指定給返回的頁面的位置 //創建modelandView對象 ModelAndView modelAndView = new ModelAndView(); //添加model(將返回給頁面的數據放入模型和視圖對象中) modelAndView.addObject("itemList", itemList); //添加視圖(指定給 返回頁面的位置) modelAndView.setViewName("jsp/itemList.jsp"); return modelAndView; } }
6、在SpringMvc.xml中配置注解掃描
這里controller類是創建在cn.clj.controller包下的
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.clj.controller"/> <mvc:annotation-driven></mvc:annotation-driven> </beans>
7、在web.xml中配置前端控制器
注意:指定核心配置文件名不能寫錯,否則會找不到Controller類
<!-- springMvc前端控制器 -->
<servlet>
<servlet-name>springMvc</servlet-name>
<!--路徑:spring-webmvc-4.1.3.RELEASE.jar\org.springframework.web.servlet -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 如果沒有指定springMvc核心配置文件那么默認會去找/WEB_INF/+<servlet-name>的內容+ -servlet.xml配置文件 -->
<!-- 指定springMvc核心配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMvc.xml</param-value>
</init-param>
<!-- tomcat啟動時就加載這個servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
DispatcherServlet的路徑為:

8、配置jsp
在WebRoot下創建jsp文件夾,用來存放jsp
1.需引入jstl標簽 2.因為傳的是itemList,接收值不能寫錯
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<body> <form action="${pageContext.request.contextPath }/search.action" method="post"> 查詢條件: <table width="100%" border=1> <tr> <!-- 如果controller接受的是vo,那么頁面上input框中name屬性值要等於vo屬性.屬性 (..)進行引用--> <td>商品名稱:<input type="text" name="items.name"/></td> <td>商品價格:<input type="text" name="items.price"/></td> <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="${itemList}" 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 }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>
9、測試
此時在瀏覽器中輸入http://localhost:8080/項目名/list.action,如果成功跳轉到顯示頁面為成功
二、關於注解處理器映射器和注解處理器適配器
注解式處理器映射器:注解式處理器映射器,對類中標記@ResquestMapping的方法進行映射,根據ResquestMapping定義的url匹配ResquestMapping標記的方法,匹配成功返回HandlerMethod對象給前端控制器,HandlerMethod對象中封裝url對應的方法Method。
注解式處理器適配器:注解式處理器適配器,對標記@ResquestMapping的方法進行適配。
方式一:手動配置最新版本的映射器和適配器(缺點:隨着版本更新的重新配置)
<!-- 配置最新版的注解的處理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 配置最新版的注解的處理器適配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
方式二:自動配置
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
全部代碼如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置@Controller注解掃描 -->
<context:component-scan base-package="cn.clj.controller"/>
<!-- 如果沒有顯示配置處理器映射器和處理器適配器那個springMvc會默認的dispatcherServlet.properties中查找
對應的處理器映射器和處理器適配器去使用,每個請求都要掃描一次的默認配置文件,效率非常低,會降低訪問速度,所以顯示的配置處理器映射器和處理器適配器
-->
<!-- 注解形式的處理器適配器
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> -->
<!-- 注解形式的處理器映射器
<bean class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"/>-->
<!-- 配置最新版的注解的處理器映射器,以上已經過時
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>-->
<!-- 配置最新版的注解的處理器適配器
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>-->
<!-- 注解驅動:能夠自動配置最新版的處理器映射器和處理器適配器 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
</beans>
三、關於視圖解析器
1.分析情形
在controller中,每次配置跳轉頁面時,都要配置跳轉視圖的全部路徑,有點麻煩
2、配置視圖解析器
功能:在配置文件中配置全局跳轉視圖的前綴名和后綴名,在controller類只要寫省去后綴的jsp名即可,配置如下:
1)在SpringMvc.xml文件中配置視圖解析器
<!-- 配置視圖解析器 --> <!-- 作用:在controller中指定頁面路徑的時候就不用寫頁面的完整路徑名稱,直接寫去掉后綴的頁面名 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--真正頁面路徑=前綴+頁面名稱+后綴 --> <!-- 跳轉視圖前綴 --> <property name="prefix" value="/jsp/"></property> <!-- 跳轉視圖后綴 --> <property name="suffix" value=".jsp"></property> </bean>
2)更改conroller類中的寫法
//添加視圖(指定給 返回頁面的位置) // modelAndView.setViewName("jsp/itemList.jsp"); modelAndView.setViewName("itemList"); return modelAndView;
四、SSM整合
個人認為,SpringMvc與Mybatis整合其實就是SSM整合,因為Spring與SpringMvc同屬於一家公司,無需整合,當然也需要用到Spring的IOC特性業務分配:此時控制層交給SpringMvc,持久層交給MyBatis,創建管理交給Spring
思路:
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配置事務。
表現層:
Springmvc.xml 1、包掃描器,掃描@Controller注解的類。 2、配置注解驅動。 3、視圖解析器 Web.xml 配置前端控制器。
1、快速部署環境
1)導入相應的依賴jar包
此包含Mybatis依賴jar包與逆向工程依賴jar包、Spring依賴jar包與Spring-mybatis整合包、SpringMVc依賴包,數據庫驅動包,第三方連接池


2)在工程項目下(非src)創建源碼包,用來存放配置文件,包名為config
3)創建分層包,采用MVC模式開發,每個包的業務不同

4)創建db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://192.168.174.132:3306/SSM jdbc.username=root jdbc.password=root
5)配置log4j.properties
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
6)創建spring核心配置文件之applicationContext-dao.xml
此文件用來管理dao層業務:配置數據源,配置SqlSessionFactory與dao層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:SqlMapConfig.xml"/> </bean> <!-- 配置Mapper掃描器 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.clj.dao"/> </bean> </beans>
7)創建spring核心配置文件之applicationContext-service.xml
此文件主要是負責業務層:開啟service注解掃描
<?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.clj.service"></context:component-scan> </beans>
8)創建spring核心配置文件之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.clj.service.*.*(..))" /> </aop:config> </beans>
9)創建SpringMvc核心配置文件之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.clj.controller"/> <!-- 注解驅動:能夠自動配置最新版的處理器映射器和處理器適配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <!-- 配置視圖解析器 --> <!-- 作用:在controller中指定頁面路徑的時候就不用寫頁面的完整路徑名稱,直接寫去掉后綴的頁面名 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--真正頁面路徑=前綴+頁面名稱+后綴 --> <!-- 跳轉視圖前綴 --> <property name="prefix" value="/jsp/"></property> <!-- 跳轉視圖后綴 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
10)配置服務器啟動掃描
整合后以上的配置文件,服務器不能自動識別加載,需要在web.xml文件中開啟包掃描
<!-- 開啟spring各核心配置文件掃描 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 開啟SpringMVc攔截器-->
<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:SpringMvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
以上整合環境部署大致完成
2、整合開發
需求1:從數據庫查詢到商品信息,並將數據返回到jsp中
1)開啟逆向工程自動生成pojo類和mapper接口和映射文件
1.1: 導入逆向工程jar包mybatis-generator-core-1.3.2
1.2 :在config包下創建generatorConfig.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="testTables" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自動生成的注釋 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--數據庫連接的信息:驅動類、連接地址、用戶名、密碼 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://192.168.174.132:3306/SSM" userId="root" password="root"> </jdbcConnection> <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --> <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和 NUMERIC 類型解析為java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成PO類的位置 --> <javaModelGenerator targetPackage="cn.clj.pojo" targetProject=".\src"> <!-- enableSubPackages:是否讓schema作為包的后綴 --> <property name="enableSubPackages" value="false" /> <!-- 從數據庫返回的值被清理前后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="cn.clj.dao" targetProject=".\src"> <!-- enableSubPackages:是否讓schema作為包的后綴 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="cn.clj.dao" targetProject=".\src"> <!-- enableSubPackages:是否讓schema作為包的后綴 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 指定數據庫表 --> <table tableName="items"></table> <table tableName="user"></table> <!-- <table schema="" tableName="sys_user"></table> <table schema="" tableName="sys_role"></table> <table schema="" tableName="sys_permission"></table> <table schema="" tableName="sys_user_role"></table> <table schema="" tableName="sys_role_permission"></table> --> <!-- 有些表的字段需要指定java類型 <table schema="" tableName=""> <columnOverride column="" javaType="" /> </table> --> </context> </generatorConfiguration>
1.3:創建啟動類
這里需要配置generatorConfig.xml文件所在路徑,並運行此類
package cn.clj.start; import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; public class StartGenerator { public void generator() throws Exception{ List<String> warnings = new ArrayList<String>(); boolean overwrite = true; File configFile = new File("config/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } public static void main(String[] args) throws Exception { try { StartGenerator startService = new StartGenerator(); startService.generator(); } catch (Exception e) { e.printStackTrace(); } } }
自動生成的文件

2、定義接口和實現類
package cn.clj.service; import java.util.List; import cn.clj.pojo.Items; public interface ItemsService { public List<Items> list() throws Exception; }
注意:這里注入了Mapper接口,並開啟了自動掃描注解
package cn.clj.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.clj.dao.ItemsMapper; import cn.clj.pojo.Items; import cn.clj.pojo.ItemsExample; @Service public class ItemsServiceImpl implements ItemsService{ @Autowired private ItemsMapper itemsMapper; @Override public List<Items> list() throws Exception { //selectByExampleWithBLOBs(example)包含文本類型 ItemsExample example=new ItemsExample(); //example.createCriteria()可以創建查詢條件;如果無需任何查詢條件,直接將example實例化即可 List<Items> list=itemsMapper.selectByExampleWithBLOBs(example); return list; } }
3、創建conroller類
@Controller public class ItemController { //注意:這里可以使用Autowired:自動裝配(缺點:當一個接口有兩個實現類時就無法世識別) //Resource:值是取實現類中定義的注解值 @Autowired private ItemsService itemsService; //查詢所有 @RequestMapping("/list") public ModelAndView itemsList() throws Exception{ List<Items> list=itemsService.list(); ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("itemList",list); modelAndView.setViewName("itemList"); return modelAndView; } }
4、創建itemList.jsp接受參數
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> <body> <form action="${pageContext.request.contextPath }/search.action" method="post"> 查詢條件: <table width="100%" border=1> <tr> <!-- 如果controller接受的是vo,那么頁面上input框中name屬性值要等於vo屬性.屬性 (..)進行引用--> <td>商品名稱:<input type="text" name="items.name"/></td> <td>商品價格:<input type="text" name="items.price"/></td> <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="${itemList}" 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 }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form> </body>
5、測試:http://localhost:8080/項目名/list.action
五、SpringMvc值參數綁定
1、關於@RequestParam標簽
1) 使用@RequestParam常用於處理簡單類型的綁定
如:jsp傳入一個值
<input type="text" name="item_id"/>
controller接收
public String editItem(@RequestParam(value="item_id",required=true) String id) { }
注意:
1.1 ) value:參數名字,即入參的請求參數名字,形參名稱為id,但是這里使用value="item_id"限定請求的參數名為item_id,所以頁面傳遞參數的名必須為item_id。如果請求參數中沒有item_id將跑出異常:
HTTP Status 500 - Required Integer parameter 'item_id' is not present
1.2)這里通過required=true限定item_id參數為必需傳遞,如果不傳遞則報400錯誤,可以使用defaultvalue設置默認值,即使required=true也可以不傳item_id參數值
2、綁定普通類型
需求1:打開編輯界面,查看商品詳情
環境:引用以上環境,當觸發itemList.jsp中的修改按鈕,根據超鏈接跳轉,傳入參數為商品id
1)、編寫接口和實現類
public Items findItemsById(Integer id) throws Exception
package cn.clj.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.clj.dao.ItemsMapper; import cn.clj.pojo.Items; import cn.clj.pojo.ItemsExample; @Service public class ItemsServiceImpl implements ItemsService{ @Autowired private ItemsMapper itemsMapper; @Override public Items findItemsById(Integer id) throws Exception { Items items=itemsMapper.selectByPrimaryKey(id); return items; } }
2)、編寫controller
參數通過域名封裝到請求中,此時可以在方法中定義HttpServletRequest、HttpSession、Model將參數獲得
注意:這里設置返回頁面是個字符串
package cn.clj.controller; import java.util.Date; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import cn.clj.pojo.Items; import cn.clj.service.ItemsService; import cn.clj.vo.QueryVo; @Controller public class ItemController { //注意:這里可以使用Autowired:自動裝配(缺點:當一個接口有兩個實現類時就無法世識別) //Resource:值是取實現類中定義的注解值 @Autowired private ItemsService itemsService;/** * springMvc默認支持的參數類型,也就是說在controller方法中可以加入這些,也可以不加 * HttpServletRequest * HttpServletResponse * HttpSession * Model */ @RequestMapping("/itemEdit") public String itemEdit(HttpServletRequest request,Model model) throws Exception{ String idStr=request.getParameter("id"); Items items=itemsService.findItemsById(Integer.parseInt(idStr)); //Model模型:模型中放入了返回給頁面的數據 //Model底層就是用的request域傳遞數據,但是對request進行了擴展 model.addAttribute("item",items); //如果springMvc方法返回一個簡單的string字符串,那么springMvc就會認為這個字符串就是頁面的名稱 return "editItem"; } }
3)、創建editItem.jsp接受參數
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <body> <!-- 上傳圖片是需要指定屬性 enctype="multipart/form-data" --> <!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> --> <form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post"> <input type="hidden" name="id" value="${item.id }" /> 修改商品信息: <table width="100%" border=1> <tr> <td>商品名稱</td> <td><input type="text" name="name" value="${item.name }" /></td> </tr> <tr> <td>商品價格</td> <td><input type="text" name="price" value="${item.price }" /></td> </tr> <tr> <td>商品簡介</td> <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea> </td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td> </tr> </table> </form> </body>
綁定pojo類型
需求2、更新數據
1)、前提有pojo類(其中在修改界面中的接受的Items 的屬性必須與pojo類中的屬性保持一致)
package cn.clj.pojo; 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; //省略set/get方法 }
1)、創建接口和實現類
public void updateItems(Items items) throws Exception;
@Service public class ItemsServiceImpl implements ItemsService{ @Autowired private ItemsMapper itemsMapper; @Override public void updateItems(Items items) throws Exception { // TODO Auto-generated method stub //此方法包含大對象文本 itemsMapper.updateByPrimaryKeyWithBLOBs(items); } }
2)、創建conroller類定義方法
@Controller public class ItemController { //注意:這里可以使用Autowired:自動裝配(缺點:當一個接口有兩個實現類時就無法世識別) //Resource:值是取實現類中定義的注解值 @Autowired private ItemsService itemsService;/** * 更新數據 * @return */ //1.springMvc可以直接接受基本數據類型,包括string,spring Mvc可以幫你自動進行類型轉換 //controller方法接受的參數的變量名稱必須要等於頁面上input框的name屬性值 //2.springMvc可以直接接受pojo類型,要求頁面上input框的name屬性名稱必須等於pojo的屬性名稱 @RequestMapping("/updateitem") public String updateitem(Items items) throws Exception{ //方式二 //public String updateitem(Integer id,String name,Float price,String detail) throws Exception{ //方式一 // Items items=new Items(); // items.setId(id); // items.setName(name); // items.setPrice(price); // items.setDetail(detail); //注意:這里jsp源代碼中屏蔽了接受時間的框,是因為String類型可以轉換為基本類型,但是string類型不能轉換為Date類型 items.setCreatetime(new Date());//數據庫字段定義為非空 itemsService.updateItems(items); return "success"; } }
3)、創建success.jsp頁面
<body> <h3>更新成功</h3> </body>
解決中文亂碼問題
1)針對post請求
post請求是封裝於服務器端,請求參數不會在域名中出現
在web.xml中配置過濾器,當服務器啟動時就對請求中的參數進行字符編碼轉換
<!-- 解決post亂碼問題 -->
<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>
2)針對get請求
get請求是響應在地址欄中,通過地址欄可以看到請求參數
將controller類中接受到的包含中文參數進行字符編碼轉換
String name=new String(request.getAttribute("參數名").getBytes("iso-8859-1"),"utf-8"));
綁定包裝類
需求3:使用包裝類接受高級查詢條件中所傳過來的值
1) 定義VO
package cn.clj.vo; import java.util.Arrays; import java.util.List; import cn.clj.pojo.Items; /** * 演示高級查詢,封裝指定pojo類中的指定屬性 * @author 佳先森 * */ public class QueryVo { //商品對象 private Items items;
//省略set/get、toString方法
}
2) 定義jsp
<form action="${pageContext.request.contextPath }/search.action" method="post">
查詢條件:
<table width="100%" border=1>
<tr>
<!-- 如果controller接受的是vo,那么頁面上input框中name屬性值要等於vo屬性.屬性 (..)進行引用-->
<td>商品名稱:<input type="text" name="items.name"/></td>
<td>商品價格:<input type="text" name="items.price"/></td>
<td><input type="submit" value="查詢"/></td>
</tr>
</table>
3) controller類中定義方法
@Controller public class ItemController { //如果controller接受的是vo,那么頁面上input框中name屬性值要等於vo屬性.屬性 (..)進行引用 @RequestMapping("/search") public String search(QueryVo vo) throws Exception{ System.out.println(vo); return ""; }
自定義參數綁定
需求:接受參數為時間格式
分析:為什么輸入框為時間格式的conroller接收時會報錯呢,是因為spring MVC能夠將自動將字符串轉換為原始型和包裝類型,但是它不能講時間格式的轉換為字符串(時間格式有多種),不然會報錯,這里只能為時間格式自定義參數綁定
1) 創建工具類
package cn.controller.converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; /** * 自定義全局字符串轉日期轉換器 * param:s -source:源 * param:T -target:目標 * 還需在springMv中配置此工具類 * @author 佳先森 * */ public class CustomGlobalStrToDateConverter implements Converter<String,Date>{ @Override public Date convert(String source) { try { Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source); return date; } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
2) 在SpringMVc上創建自定義轉換器,並將它配置到注解驅動上
<!-- 注解驅動:能夠自動配置最新版的處理器映射器和處理器適配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <!-- 配置自定義轉換器:用於將字符串轉換為日期格式 步驟:1.編寫工具類 2.將自定義的轉換器配置到注解驅動上 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <!-- 指定自定義轉換器的全路徑名名稱 --> <bean class="cn.controller.converter.CustomGlobalStrToDateConverter"/> </set> </property> </bean>
3) jsp界面
注意引入jstl/fmt標簽,這是能夠在界面中對時間內容進行格式整理
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post"> <table width="100%" border=1> <tr> <td>商品生產日期</td> <td><input type="text" name="createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td> </tr> </table> </form>
4) controller接收方法
@RequestMapping("/updateitem")
public String updateitem(Items items,Model model) throws Exception{
itemsService.updateItems(items);
return "success";
}
六、spring MVC與struts 2區別
1、 springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過慮器。
2、 springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,可以設計為單例或多例(建議單例),struts2是基於類開發,傳遞參數是通過類的屬性,只能設計為多例。
3、 Struts采用值棧存儲請求和響應的數據,通過OGNL存取數據, springmvc通過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最后又將ModelAndView中的模型數據通過reques域傳輸到頁面。Jsp視圖解析器默認使用jstl。
七、spring MVC高級參數綁定
1、綁定數組
需求:演示批量刪除
1) 定義jsp
jsp中包含一個form表單,多個input框前有個checkbox復選框
<form action="${pageContext.request.contextPath }/delAll.action" method="post">
查詢條件:
<table width="100%" border=1>
<tr>
<!-- 如果controller接受的是vo,那么頁面上input框中name屬性值要等於vo屬性.屬性 (..)進行引用-->
<td>商品名稱:<input type="text" name="items.name"/></td>
<td>商品價格:<input type="text" name="items.price"/></td>
<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="${itemList}" var="item">
<tr>
<!-- 批量刪除:name屬性名稱等於vo中的接受的屬性名稱 -->
<td>
<input type="checkbox" name="ids" value="${item.id}"/>
</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>
</table>
</form>
2)定義controller中的方法
這里是通過復選框將選中的數據進行傳送,controller方法中得用數組來接收
方式一:數組作為參數進行接收:注意這里屬性名(ids)要與復選框保持一致
//如果批量刪除,一堆input復選框,那么可以提交數據(只有被選中的時候才可以提交) @RequestMapping("/delAll") public String delAll(String[] ids) throws Exception{ System.out.println(ids.toString()); return ""; }
方式二:將數組作為屬性封裝到VO對象中,將VO對象作為參數進行接收
public class QueryVo { //商品對象 private Items items; //批量刪除 private Integer[] ids; //省略set/get方法 }
//如果批量刪除,一堆input復選框,那么可以提交數據(只有被選中的時候才可以提交) @RequestMapping("/delAll") public String delAll(QueryVo vo) throws Exception{ System.out.println(vo.getItems().getName()); System.out.println(queryVo.getItems().getPrice()); return ""; }
2、綁定集合(將表單的數據綁定到List中)
需求:對數據進行批量修改
1) 在pojo類中定義一個集合的屬性
package cn.clj.vo; import java.util.Arrays; import java.util.List; import cn.clj.pojo.Items; /** * 演示高級查詢,封裝指定pojo類中的指定屬性 * @author 佳先森 * */ public class QueryVo { //商品對象 private Items items; //用戶對象 //。。。。 //批量刪除 private Integer[] ids; //批量修改 private List<Items> itemsList; //省略set/get,toString()方法 }
2)更改jsp
<form action="${pageContext.request.contextPath }/updateAll.action" method="post"> 查詢條件: <table width="100%" border=1> <tr> <!-- 如果controller接受的是vo,那么頁面上input框中name屬性值要等於vo屬性.屬性 (..)進行引用--> <td>商品名稱:<input type="text" name="items.name"/></td> <td>商品價格:<input type="text" name="items.price"/></td> <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="${itemList}" var="item" varStatus="status"> <tr> <!-- 如果批量修改,可以用List<pojo>來接受,頁面上input框的name屬性值=vo中的接受的屬性名稱+[list的下標]+.+list泛型屬性的名稱 --> <td> <input type="checkbox" name="ids" value="${item.id}"/> <input type="hidden" name="itemsList[${status.index}].id" value="${item.id}"/> </td> <td><input type="text" name="itemsList[${status.index}].name" value="${item.name}"/></td> <td><input type="text" name="itemsList[${status.index}].price" value="${item.price}"/></td> <td><input type="text" name="itemsList[${status.index}].createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td> <td><input type="text" name="itemsList[${status.index}].detail" value="${item.detail}"/></td> <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>
3)在controller類中創建接受方法
//批量修改 @RequestMapping("/updateAll") public String updateAll(QueryVo vo) throws Exception{ System.out.println(vo.getItems().getName());
System.out.println(vo.getItems().getPrice());
return "";
}
八、關於spring MVC窄化請求映射
分析:在團隊開發情況下,不同controller中可能出現一個或多個方法RequestMapping值相同,因為配置文件中采用的是包掃描的方法進行映射,就有可能在輸入域名的時候跳錯controller中的方法。此時,如果為了區分每個conroller中的每個方法,必須配置窄化請求映射,相當於給類起個名字,每當反問域名時,指定跳轉方法uri前必須加上這個“類名”,通過此方法對類行進分類管理
如:
@Controller //窄化請求映射:為防止方法名重名,相當於在url中多加了一層目錄,房子重名 @RequestMapping("/items") public class ItemController { //批量修改 @RequestMapping("/updateAll") public String updateAll(QueryVo vo) throws Exception{ System.out.println(vo); return ""; }
如果以后要跳轉到該方法,域名得寫成http://localhost:8080/項目名/items/updateAll.action
九、spring MVC之請求方法限定
語法為@RequestMapping(value="/XXX",method=RequestMethod.XX),其中XX可以寫GET或者POST,如果在方法中限定了請求方法而jsp中表單提交方式不是指定的,會報405錯誤
@RequestMapping(value="/list",method=RequestMethod.GET) public ModelAndView itemsList() throws Exception{ List<Items> list=itemsService.list(); System.out.println("進入了"); ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("itemList",list); modelAndView.setViewName("itemList"); return modelAndView; }
十、controller類方法返回值
controller方法返回值包含多種,一下介紹幾種常用的:
1、ModelAndView方式
@RequestMapping(value="/list",method=RequestMethod.GET) public ModelAndView itemsList() throws Exception{ List<Items> list=itemsService.list(); ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("itemList",list); modelAndView.setViewName("itemList"); return modelAndView; }
2、String方式(直接return一個字符串),返回的數據由model完成
種類一:放回普通字符串(去掉頁面擴展名)
@RequestMapping("/search")
public String search(QueryVo vo) throws Exception{
System.out.println(vo);
return "success";
}
種類二:請求轉發方式
注意:這里是請求轉發跳轉到同一個Controller中的注解值為itemEdit的方法,請求轉發能夠攜帶值
@RequestMapping("/updateitem")
public String updateitem(Items items,Model model) throws Exception{
itemsService.updateItems(items);//請求轉發:瀏覽器中的url不發生改變,request域中的數據可以帶到轉發后的方法中
model.addAttribute("id",items.getId());//或者:request.setAttribute("id",items.getId())
//springMvc中請求轉發:返回的字符串以forward:開頭的都是請求轉發
return "forward:itemEdit.action";
}
種類三:重定向方式
注意:重定向的方式是不能攜帶值的,如果要傳參數,得封裝到域名中(如:return "redirect:itemsEdit.action?id="+items.getId())
@RequestMapping("/updateitem")
public String updateitem(Items items,Model model) throws Exception{
itemsService.updateItems(items);
model.addAttribute("id",items.getId());//在springMvc中凡是以redirect:字符串開頭的的都是重定向
return "redirect:itemsEdit.action";
}
種類三:返回值為void
這里演示的請求請求轉發的方式(如果controller方法返回值為void,則不走SpringMvc組件,需要些完整的路徑名稱))
@RequestMapping("/updateitem")
public void updateitem(Items items,HttpServletRequest request,HttpServletResponse response) throws Exception{
itemsService.updateItems(items);
request.setAttribute("id",items.getId())
request.getRequestDispatcher("/jsp/success.jsp").forward(request, response);
}
十一、spring MVC之全局異常處理
需求:當條件查詢詢信息時出現錯誤(沒有該商品),都會跳轉到指定的錯誤頁面
1、定義異常類
package cn.clj.vo; public class CustomerException extends Exception{ //異常信息 private String message; public CustomerException(String message) { super(); this.message = message; } //省略set/get方法 }
2、定義異常處理工具類
public class GlobalExceptionResolver implements HandlerExceptionResolver{ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ex.printStackTrace(); CustomerException customerException=null; if(ex instanceof CustomerException){ customerException=(CustomerException) ex; }else{ customerException=new CustomerException("系統錯誤,請聯系管理員"); } ModelAndView model=new ModelAndView(); model.addObject("message",customerException); model.setViewName("error"); return model; } }
3、創建異常頁面error.jsp
<body>
您的操作出現錯誤如下:<br/>
<h3><font color="red">${message}</font></h3>
</body>
4、配置異常處理(在SpingMvc.xml文件中配置處理器)
<!-- 異常處理器 -->
<bean id="handlerExceptionResolver" class="cn.clj.vo.CustomerException"/>
</beans>
5、利用異常類
在調用查詢方法時,如果查詢到的商品不存在,拋出自定義異常類
@RequestMapping("/itemEdit")
public String itemEdit(HttpServletRequest request,Model model) throws Exception{
String idStr=request.getParameter("id");
Items items=itemsService.findItemsById(Integer.parseInt(idStr));
if(items==null){
throw new CustomerException("您查詢的信息不存在");
}
model.addAttribute("item",items);
return "editItem";
}
6、測試
當查詢一個不存在的商品,如果成功跳轉到自定義異常界面,表示配置成功
十二、spring MVC之上傳圖片
分析:企業中像那種高並發項目,都會有不同的服務器接受不同資源,利用nginx實現負載均衡。這里因為只上傳圖片,服務器只有tomcat,所以只能在tomcat中配置。
1、配置虛擬存儲路徑
此配置就是將上傳的圖片放置到指定的文件夾下
做法:進入tomcat/conf/server.xml文件中,加入下面一條命令,表示到域名以pic結尾時,訪問的目錄為E:\壁紙文件夾下
<Context docBase="E:\壁紙" path="/pic" reloadable="false"/>
2、加入文件上傳依賴jar包

3、在SqlMapConfig.xml中配置文件上傳解析器
<!-- 文件上傳 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設置上傳文件的最大尺寸為5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
4、在Controller中創建文件上傳處理方法
文件上傳是通過表單提交的,所提交的是一連串字符串,需對字符串進行處理,這里為了防止所存的圖片文件重名,采用了隨機字符串進行拼接
//演示上傳圖片:注意"pictureFile"是與jsp中文件上傳屬性保持一致 @RequestMapping("/upload") public String upload(MultipartFile pictureFile,Items items,Model model) throws Exception{ //1.獲取圖片完整名稱 String fileStr=pictureFile.getOriginalFilename(); //2.使用隨機生成的字符串+源圖片擴張名組成新的圖片名稱,防止圖片重名 String newFileName=UUID.randomUUID().toString()+fileStr.substring(fileStr.lastIndexOf(".")); //3.將圖片保存到硬盤 pictureFile.transferTo(new File("E:\\壁紙\\"+newFileName)); //4.將圖片名稱保存到數據庫 items.setPic(newFileName); itemsService.updateItems(items); return "success"; }
5、創建具有圖片上傳的form表單的jsp頁面
<form id="itemForm" action="${pageContext.request.contextPath }/upload.action" method="post" enctype="multipart/form-data">
<table width="100%" border=1>
<tr>
<td>商品圖片</td>
<td>
<c:if test="${item.pic!=null}">
<img src="/pic/${item.pic}" width=100 height=100/>
<br/>
</c:if>
<input type="file" name="pictureFile"/>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
</td>
</tr>
</table>
</form>
十三、spring MVC之Json
spring MVC是支持Json格式的,需要配置@RequestBody
@RequestBody注解用於讀取http請求的內容(字符串),通過springmvc提供的HttpMessageConverter接口將讀到的內容轉換為json、xml等格式的數據並綁定到controller方法的參數上。
需求:利用ajax傳送json數據,contoller類定義方法進行接受,並進行相應
1、導入json依賴jar包

2、必須有注解驅動,基於上面環境已經配置,這里無須再配置
<!-- 注解驅動:能夠自動配置最新版的處理器映射器和處理器適配器 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
3、導入jquery依賴jar包
4、jsp中調用ajax請求
這里當觸發input按鈕,就會調用ajax請求
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
function sendJson(){
$.ajax({
type:"post",
url:"${pageContext.request.contextPath }/sendJson.action",
<!--ajax默認以text文本形式傳遞,如果要傳遞json的指定為json-->
contentType:"application/json;charset=utf-8",
data:'{"name":"測試商品","price":99.9}',
success:function(data){
alert(data);
}
});
}
</script>
<input type="button" value="sendJson" onClick="sendJson()"/>
5、參數接受
//導入jackson的jar包在controller的方法中可以使用@RequestBody, //讓springMvc將json格式字符串自動轉換我java中pojo //注意:頁面json中key要等於java中pojo的屬性名稱 //controller方法返回pojo類型的對象並且用@ResponseBody注解,springMvc會自動將pojo對象轉換為json格式字符串 @RequestMapping("/sendJson") @ResponseBody public Items sendJson(@RequestBody Items items) throws Exception{ //public void sendJson(@RequestBody Items items) throws Exception{ System.out.println(items.getName()+"\t"+items.getPrice()); //方式一,返回值為void這里無須設置跳轉頁面,ajax會自動跳轉 //方式二:返回值為Items pojo類,方法中參數必須配置@ResponseBody注解,會給界面返回Item 對象 return items; }
十四、spring MVC之Restful風格
1、什么是Restfull風格
一種軟件架構風格,設計風格而不是標准,只是提供了一組設計原則和約束條件。它主要用於客戶端和服務器交互類的軟件。基於這個風格設計的軟件可以更簡潔,更有層次,更易於實現緩存等機制。
------ 360百科
簡而言之:Restful就是一個資源定位及資源操作的風格。不是標准也不是協議,只是一種風格,是對http協議的詮釋。
資源定位:互聯網所有的事物都是資源,要求url中沒有動詞,只有名詞。沒有參數
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
資源操作:使用put、delete、post、get,使用不同方法對資源進行操作。分別對應添加、刪除、修改、查詢。一般使用時還是post和get。Put和Delete幾乎不用。
2、怎么使用Restful
需求:更改訪問路徑格式,采用Restful風格
1) 配置restful配置
此時需要更改web.xml文件中的攔截對象,以前是針對所有的action("*.action"),現在是針對所有對象("/")
<!-- 開啟SpringMVc攔截器-->
<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:SpringMvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMvc</servlet-name>
<!--
*.action:代表攔截后綴名為.action結尾的
/ :攔截所有但是不包括.jsp
/* :攔截所有包括.jsp
-->
<url-pattern>/</url-pattern> </servlet-mapping>
2) jsp請求書寫規范
這里是傳遞了一個id參數,請求域名中去掉了aciton或者特殊符號
<a href="${pageContext.request.contextPath }/restful/${item.id}">修改</a>
3) 接受參數
通過@RequestMapping("/restful/{id}")接收具有restful風格的域名;@PathVariable 接受參數值
//通過@PathVariable可以接收url中所傳過來的參數 //@RequestMapping("/restful/{id}/{張三}")傳多參 //@RequestMapping("/restful/{id}")中接受參數使用大括號中加上變量名稱,@PathVariable中變量名稱要和@RequestMapping中變量名稱保持一致 @RequestMapping("/restful/{id}") public String restful(@PathVariable("id") Integer id,HttpServletRequest request,Model model) throws Exception{ // public String restful(@PathVariable("id") Integer id,@PathVariable("張三") String name,HttpServletRequest request,Model model) throws Exception{ Items items=itemsService.findItemsById(id); model.addAttribute("item",items); return "editItem"; }
十五、spring MVC之攔截器
1、怎么定義一個攔截器
1) 創建一個自定義攔截器類,繼承HandlerInterceptor接口
package cn.clj.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class Interceptor1 implements HandlerInterceptor{ //執行實際:Controller以及執行,ModelAndView已經返回 //使用場景:記錄操作日志(如記錄用戶登錄的ip,時間等) @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("afterCompletion"); } //執行實際:Controller方法已經執行,ModelAndView還沒返回 //使用場景:可以再次方法中設置全局的數據處理業務,這里有個ModelAndView,可以添加全局參數 @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub System.out.println("postHandle"); } //返回boolean值:如果返回true:放行;false:攔截 //執行時機:controller方法沒有被執行,ModelAndView沒有被返回 //使用場景:權限驗證 @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { // TODO Auto-generated method stub System.out.println("preHandle"); return true; } }
2) 在springMvc.xml配置攔截器(這里是配置全局攔截器)
<!-- 配置攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!--攔截請求的路徑要攔截所有必須配置成/**(不能是/*,它只攔截一層目錄) -->
<mvc:mapping path="/**"/> 指定攔截器的位置 <bean class="cn.clj.interceptor.Interceptor1"/> </mvc:interceptor> </mvc:interceptors>
3)啟動tomcat,就會自動調用攔截器
2、攔截器應用之登錄(身份認證)
分析:在登錄界面中,當用戶輸入自己信息時,會調用后端方法,攔截器檢查session中否存在這個用戶,核對數據庫是否有這個用戶,然后進行處理放心還是攔截
1) 定義一個登錄的攔截器
package cn.clj.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginInterceptor implements HandlerInterceptor{ @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { //判斷當前訪問路徑是否為登錄的路徑,如果是則放行 if(request.getRequestURI().indexOf("/login")>0){ return true; } //判斷session中是否有登錄信息,如果沒有則跳轉到登錄界面,如果有則放行 HttpSession session=request.getSession(); if(session.getAttribute("username")!=null){ return true; } request.getRequestDispatcher("/jsp/login.jsp").forward(request, response); //其他則攔截 return false; } }
2) 定義一個jsp登錄界面
<form action="${pageContext.request.contextPath}/login/submit" method="post">
<table>
<tr>
<td>用戶名:<input type="text" name="username"/></td></br>
<td>密 碼:<input type="text" name="password"/></td></br>
<td><input type="submit" value="登錄"/></td>
</tr>
</table>
</form>
3) 定義處理登錄的controller類
package cn.clj.controller; import java.io.File; import java.util.Date; import java.util.List; import java.util.UUID; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import cn.clj.pojo.Items; import cn.clj.service.ItemsService; import cn.clj.vo.QueryVo; @Controller @RequestMapping("/login") public class LoginController { //跳轉到登錄頁面 @RequestMapping("/login") public String login() throws Exception{ return "login"; } @RequestMapping("/submit") public String submit(String username,String password,HttpServletRequest request) throws Exception{ HttpSession session=request.getSession(); //判斷用戶名密碼正確性,如果正確則將登錄信息放入session中 //這里簡寫,真正項目中要去數據庫中校驗用戶名和密碼 if(username!=null){ session.setAttribute("username", username); } //跳轉到列表頁(注意:這里加了斜杠是用了絕對路徑,因為 //兩者不屬於同一個controller,如果跳轉的conrtoller //類前加了窄化請求映射,路徑名得為redirect:/items/list) return "redirect:/list"; } }
