SpringMVC學習筆記_02
1、springmvc對多檢視的支援
(1)匯入xml格式檢視支援的jar包
注意:springmvc本身就支援xml格式,所以不用匯入其他支援的jar包了。
(2)在springmvc.xml中配置支援多檢視
<!-- 配置支援多檢視 -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<!-- 配置支援的媒體型別 -->
<!-- spring3.2後改成如下配置 -->
<property name="contentNegotiationManager">
<bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<!-- 指定多個媒體型別 -->
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"></entry>
<entry key="xml" value="application/xml"></entry>
<!-- <entry key="pdf" value="application/pdf"></entry> 需要額外的jar包 -->
</map>
</property>
</bean>
</property>
<!-- 指定預設的檢視 -->
<property name="defaultViews">
<!-- 支援多個檢視 -->
<list>
<!-- 對json格式檢視的支援 -->
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"></bean>
<!-- 對xml格式檢視的支援,需要注入建構函式,需要一個jar包:spring-oxm-3.2.0.RELEASE.jar -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<!-- 配置對哪些類進行xml轉換的支援,即繫結多個類,演示程式碼中我們只綁定了一個類 -->
<property name="classesToBeBound">
<list>
<!-- 注意:需要在繫結的類中加入對xml格式檢視轉換的註解:@XmlRootElement -->
<value>com.itheima.domain.User</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
</bean>
小結:通過以上配置,模擬了WebService對多檢視的支援的功能。
(3)配置javabean,即在繫結的類User中加入對xml格式檢視轉換的註解:@XmlRootElement
(4)在web.xml中配置約定訪問的url
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
(5)定義Controller
// 多檢視支援
// 返回的是物件,把返回的物件轉換成json格式檢視和xml格式的檢視
@RequestMapping("multiView")
public User multiView() {
User user1 = new User();
user1.setId(1);
user1.setUsername("曉藝");
user1.setAge("26");
user1.setAddress("物資學院");
user1.setBirthday(new Date());
return user1;
}
(6)訪問
根據官方文件約定:訪問的時候需要加上響應的副檔名。
即:訪問json格式的資料,需要加上json副檔名;訪問html格式的資料,需要加上html的副檔名;訪問xml格式的資料,需要加上xml的副檔名。
根據我們web.xml檔案的訪問約定:副檔名.do是訪問jsp頁面的。
我們約定rest目錄下所有以json和xml副檔名都支援相應的檢視。
我們訪問json格式資料的訪問形式如下:
我們訪問xml格式資料的訪問形式如下:
(7)<mvc:annotation-driven/>
<mvc:annotation-driven/> 預設建立:註解處理器對映器、註解處理器介面卡、並提供對json格式資料的支援。
在springmvc.xml中進行配置:
<!-- 表示預設建立:處理器對映器物件、處理器對映器物件,還表示預設啟動json格式資料的支援 -->
<mvc:annotation-driven />
但是注意:此時javaBean不能添加註解@XmlRootElement了。@XmlRootElement表示提供對xml檢視支援。
2、SSM整合小案例
2.0、需求
- 實現商品查詢列表,從mysql資料庫中查詢商品資訊。
2.1、使用eclipse,建立一個動態web工程並匯入jar包
- 其中Dynamic web module version版本選擇 2.5,這樣相容性好一些;
- Default output folder設定為 WebRoot\WEB-INF\classes
- Content directory設定為 WebRoot
- 更改JRE System Library[J2SE-1.5]為 JRE System Library[jre1.7.0_80]
- 刪掉沒用的庫:EAR Libraries
- 增加伺服器執行環境庫 Server Runtime,不然jsp檔案會報錯。
- 建立完專案後,將整個專案的編碼改為UTF-8。
- 操作步驟:選中專案右鍵 --> Properties --> Resource --> Text file encoding --> Other中選擇UTF-8。
- 對於動態的java web專案,為了工程目錄結構的清爽,我們將引入的jar包放到“Web App Libraries”中,可以通過“小三角”選擇是否“Show 'Referenced Libraries' Node ”進行調節。
- 對於普通的java專案,為了工程目錄結構的清爽,我們將引入的jar包放到“Referenced Libraries”中,可以通過“小三角”選擇是否“Show 'Referenced Libraries' Node ”進行調節。
匯入jar包
包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、資料庫驅動、第三方連線池、jstl、c3p0管理資料來源、log4j、junit。
參考:“mybatis與springmvc整合全部jar包”目錄。
本次案例共匯入28個jar包。如下圖所示:
2.2、web.xml配置檔案(入口)
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>day63_SpringMVC_01</display-name>
<!-- 配置spring編碼過濾器 -->
<filter>
<filter-name>characterEcoding</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>characterEcoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置前端控制器:DispatcherServlet -->
<servlet >
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 顯示配置載入springmvc.xml檔案,即配置springmvc.xml檔案的初始化引數 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<!-- 配置servlet攔截副檔名 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 配置servlet攔截目錄 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- 配置載入spring的配置檔案:beans.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value> <!-- 這兩種方式均可 -->
<!-- <param-value>/WEB-INF/classes/beans.xml</param-value> -->
</context-param>
<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>
</web-app>
2.3、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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 配置掃描,把Controller交給spring管理 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!-- 表示預設建立處理器對映器物件、處理器對映器物件,還表示預設啟動json格式資料的支援 -->
<mvc:annotation-driven />
<!-- 配置jsp檢視解析器,InternalResourceViewResolver負責解析出真正的邏輯檢視 -->
<!-- 後臺返回邏輯檢視:index,jsp檢視解析器解析出真正的物理檢視:字首+邏輯檢視+字尾 ==>/WEB-INF/jsps/index.jsp -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
2.4、bean.xml配置檔案(相當於applicationContext.xml)
bean.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<context:component-scan base-package=""></context:component-scan>
<!-- 1、配置資料來源 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 2、配置sqlSessionFactory,用於生產sqlSession -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
</bean>
<!-- 配置mybatis的Mapper介面代理開發,需要遵循的幾點規範 -->
<!--
1、mapper介面的全限定名要和mapper對映檔案的namespace的值相同。
2、mapper介面的方法名稱要和mapper對映檔案中的statement的id相同。
3、mapper介面的方法引數只能有一個,且型別要和mapper對映檔案中statement的parameterType的值保持一致。
4、mapper介面的返回值型別要和mapper對映檔案中statement的resultType的值或resultMap中的type的值保持一致。
5、mapper介面和mapper對映檔案必須在同一目錄下。
-->
<!-- mapper代理開發方式之批量mapper配置,預設bean的id為類名首字母小寫 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定批量mapper配置的包名 -->
<property name="basePackage" value="com.itheima.dao"></property>
<!-- 當只有一個SqlSessionFactory時,預設是不需要配置SqlSessionFactory的 -->
<!-- 當有多個SqlSessionFactory時,可以指定使用的SqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- 3、配置事務管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置通知:管理事務的策略 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置攔截service:切面程式設計 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.*.*(..))"/>
</aop:config>
</beans>
2.6、編寫程式碼
mapper層(dao層):
mapper介面程式碼使用Mybatis的逆向工程生成的。
service層:
ItemsService.java
public interface ItemsService {
public List<Items> findAll();
public Items findById(Integer id);
public void saveOrUpdate(Items items);
public void deleteById(Integer id);
}
ItemsServiceImpl.java
@Service
public class ItemsServiceImpl implements ItemsService {
// 注入介面物件(Mapper介面使用代理類)
@Resource
private ItemsMapper itemsMapper;
public List<Items> findAll() {
List<Items> list = itemsMapper.findAll();
return list;
}
public Items findById(Integer id) {
Items items = itemsMapper.selectByPrimaryKey(id);
return items;
}
public void saveOrUpdate(Items items) {
itemsMapper.updateByPrimaryKey(items); // 商品id通過頁面隱藏域傳過來的
}
public void deleteById(Integer id) {
itemsMapper.deleteByPrimaryKey(id);
}
}
controller層(web層/Action層):
ItemsController.java
@Controller
@RequestMapping("/items")
public class ItemsController {
// 注入service物件
@Resource
private ItemsService itemsService;
// 查詢所有商品方法
@RequestMapping("list")
// springmvc使用Model物件進行頁面資料回顯,Model物件相當於javaweb時所學的application物件(應用域物件),所以Model物件中的資料,在頁面上可以通過EL表示式進行獲取。
// 有了Model物件,才可以向物件中放值,那麼Model物件該如何建立呢?
// 答:“由於springmvc中放到方法裡面的物件會自動被建立”,那麼我們就把Model物件放到方法裡面。
public String list(Model model) {
List<Items> itemsList = itemsService.findAll();
model.addAttribute("itemsList", itemsList);
return "itemsList";
}
// 修改商品方法
@RequestMapping("editById")
public String editById(Integer id, Model model) {
// 跟據id查詢商品
Items items = itemsService.findById(id);
model.addAttribute("items", items);
return "editItems";
}
// 修改後儲存方法
@RequestMapping("saveOrUpdate")
public String saveOrUpdate(Items items) {
itemsService.saveOrUpdate(items); // 商品id通過頁面隱藏域傳過來的
return "redirect:list.do";
}
// 跟據id進行刪除
@RequestMapping("deleteById")
public String deleteById(Integer id) {
itemsService.deleteById(id);
return "redirect:list.do";
}
// 跟據ids進行批量刪除
@RequestMapping("deleteByIds")
public String deleteByIds(Integer[] ids) { // 特別注意:標籤input的name的屬性值id要與方法的形式引數名稱id相同。形參名稱也可以起別名!但需要其他註解配合哦!
for (Integer id : ids) {
itemsService.deleteById(id);
}
return "redirect:list.do";
}
}
2.7、springmvc檔案上傳
需求分析:
使用ajax,響應json格式資料的形式上傳圖片並立刻回顯。頁面不重新整理圖片回顯立刻。
ajax能不能提交表單?
答:ajax自己不能提交表單。要想ajax提交表單,需要藉助一個外掛。
為什麼我們要提交表單?
答:因為我們要提交一個檔案物件,需要將檔案物件關聯到表單裡面。
當我們點選一個按鈕的時候,這個被關聯到表單裡的物件,才會被提交。
虛擬碼示例如下:
// 圖片回顯
<img src=“圖片路徑”/>
// 把檔案關聯表單,觸發ajax事件
<input type="file" onchange="ajax事件"/>
<input type="hidden" value="圖片相對路徑"/>
// 本示例開始,我們不使用 enctype="multipart/form-data" 提交檔案物件了
// 我們直接使用ajax提交檔案物件,我們新增隱藏域,向後臺提交圖片相對路徑
(1)匯入跨伺服器上傳檔案的jar包、IO、fileupload
(2)模擬2臺伺服器
建立一個動態的java web專案:圖片伺服器專案,圖片伺服器專案的伺服器和上傳圖片專案的伺服器埠不一致即可。如下圖所示:
(3)springmvc支援檔案上傳,需要先在springmvc.xml配置檔案中開啟檔案上傳
在springmvc.xml配置檔案中新加入的內容如下:
<!-- 配置開啟檔案上傳,因為我們要跨伺服器上傳,需要寫上id,該id名稱固定 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置檔案上傳大小 -->
<property name="maxUploadSize" value="1024000"></property>
</bean>
(4)前臺頁面ajax
功能:傳送請求,請求上傳圖片,圖片需要被關聯在表單裡。
使用ajax提交form表單的外掛:jquery.form.js
(5)後臺程式碼
@Controller
@RequestMapping("/upload")
public class UploadController {
@RequestMapping("uploadPic")
public void uploadPic(HttpServletRequest request, String fileName, PrintWriter out) {
// 1、準備檔案上傳流
// 由於上傳的圖片在請求裡面,它是流型別的,直接通過Request物件不能操作
// 所以先要把Request物件強轉成多部件請求物件
MultipartHttpServletRequest mhr = (MultipartHttpServletRequest) request;
// 根據檔名稱獲取普通多部件檔案物件
CommonsMultipartFile cmFile = (CommonsMultipartFile) mhr.getFile(fileName);
// 獲取檔案上傳流
byte[] fbytes = cmFile.getBytes();
// 2、準備檔名稱
// 檔名稱在伺服器有可能重複,我們使用時間來區分他們
String newFileName = "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
newFileName = sdf.format(new Date());
// 在毫秒的時候檔名也可能重複,我們再加點鹽
Random r = new Random(); // [0,1)
for (int i = 0; i < 3; i++) {
newFileName = newFileName + r.nextInt(10);
}
// 3、獲取副檔名
String originalFilename = cmFile.getOriginalFilename();
// int x = a.lastIndexOf(b); // 表示b字串在a字串中最後出現的位置,從0開始
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// 4、建立jesy伺服器,進行跨伺服器上傳
Client client = Client.create();
// 把檔案關聯到遠端伺服器
// 圖片檔案的完整路徑為:http://127.0.0.1:9005/day64_SSMImageServer/upload/20181027174523998.png
WebResource resource = client.resource(Commons.PIC_HOST + "/upload/" + newFileName + suffix);
// 上傳圖片檔案
resource.put(String.class, fbytes);
// 5、ajax回撥函式需要回顯什麼東西呢?
// 圖片需要回顯:需要圖片的完整路徑
// 資料庫儲存圖片:需要圖片的相對路徑
String fullPath = Commons.PIC_HOST + "/upload/" + newFileName + suffix;
String relativePath = "/upload/" + newFileName + suffix;
// json格式的資料:{"":"","":""}
String result = "{\"fullPath\":\"" + fullPath + "\",\"relativePath\":\"" + relativePath + "\"}";
out.print(result);
}
}
(6)修改圖片伺服器檔案上傳許可權
(7)圖片上傳位置
(8)圖片列表回顯
回顯圖片需要使用<img/>標籤
itemsList.jsp
<c:set var="picPath" value="http://127.0.0.1:9090/day64_SSMImageServer"></c:set>
......
<td>
<img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
</td>