1 前言
在史上最簡單的 Spring MVC 教程(五拌滋、六、七猜谚、八)等四篇博文中败砂,咱們已經(jīng)分別實(shí)現(xiàn)了“人員列表”的顯示、添加魏铅、修改和刪除等常見的增昌犹、刪、改览芳、查功能斜姥。接下來,也就是在本篇博文中沧竟,咱們在繼續(xù)實(shí)現(xiàn)新的功能铸敏,即:上傳圖片和顯示圖片。
2 注解示例 - 上傳及顯示圖片
老規(guī)矩屯仗,首先給出項(xiàng)目結(jié)構(gòu)圖:
2.1 顯示圖片
第一步:修改 web.xml 文件搞坝,攔截所有的 URL
<?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">
<!-- 配置 Spring 框架 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置 DispatcherServlet,對所有后綴為action的url進(jìn)行過濾 -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 修改 Spring MVC 配置文件的位置和名稱 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/</url-pattern> <!-- 攔截所有的 URL -->
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
第二步:修改 springmvc-servlet.xml 文件魁袜,增加靜態(tài)資源的管理
<?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" 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 ">
<!-- 聲明注解開發(fā)方式 -->
<mvc:annotation-driven/>
<!-- 靜態(tài)資源的管理 -->
<mvc:resources location="/upload/" mapping="/upload/**"/>
<!-- 包自動掃描 -->
<context:component-scan base-package="spring.mvc.controller"/>
<!-- 內(nèi)部資源視圖解析器桩撮,前綴 + 邏輯名 + 后綴 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
第三步:修改 web 目錄下的 index.jsp 頁面敦第,增加跳轉(zhuǎn)鏈接及顯示圖片
<%-- Created by IntelliJ IDEA. User: 維C果糖 Date: 2017/1/29 Time: 21:25 To change this template use File | Settings | File Templates. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Spring MVC</title>
</head>
<body>
This is my Spring MVC!<br>
<a href="${pageContext.request.contextPath}/person/all.action">顯示人員列表</a>
<img src="${pageContext.request.contextPath}/upload/SoCuteCat.jpg">
</body>
</html>
在完成以上步驟后,啟動 tomcat 服務(wù)器店量,默認(rèn)訪問 http://localhost:8080/springmvc-annotation/芜果,頁面如下所示:
然后,點(diǎn)擊“顯示人員列表”融师,將訪問 http://localhost:8080/springmvc-annotation/person/all.action右钾,頁面如下所示:
額外提示:在大型網(wǎng)站的框架中,常見的配置是動態(tài)資源和靜態(tài)資源分別解析旱爆,主要有兩種選擇舀射,分別是
- 第一種:Apache + tomcats(集群)
- 第二種:Nginx + tomcats(集群)
其中,Apache 和 Nginx 是負(fù)責(zé)負(fù)載均衡怀伦,即平均分配資源脆烟,同時(shí)用它們來解析靜態(tài)資源,例如 JavaScript房待、CSS 和 Image 等邢羔;tomcat 集群負(fù)責(zé)動態(tài)資源的解析,例如 jsp 和 action 等桑孩。至于為什么會衍生出用 Nginx 代替 Apache 的第二種方案拜鹤,主要是因?yàn)?Nginx 的處理速度是 Apache 的 100 倍。
2.2 上傳圖片
第一步:修改實(shí)體類(Person)流椒,添加圖片存儲路徑的字段
package spring.mvc.domain;
/** * Created by 維C果糖 on 2017/1/30\. */
public class Person {
private Integer id;
private String name;
private Integer age;
private String photoPath; // 圖片存儲路徑
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhotoPath() {
return photoPath;
}
public void setPhotoPath(String photoPath) {
this.photoPath = photoPath;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
第二步:修改控制器(PersonController)中的 updatePersonList 方法
package spring.mvc.controller;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import spring.mvc.domain.Person;
import spring.mvc.service.PersonService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/** * Created by 維C果糖 on 2017/1/26\. */
@Controller
public class PersonController {
@Resource
PersonService ps; // 注入 service 層
@RequestMapping(value = "/person/all")
public String findAll(Map<String, Object> model) { // 聲明 model 用來傳遞數(shù)據(jù)
List<Person> personList = ps.findAll();
model.put("personList", personList); // 通過這一步敏簿,JSP 頁面就可以訪問 personList
return "/person/jPersonList"; // 跳轉(zhuǎn)到 jPersonList 頁面
}
@RequestMapping("/person/toCreatePersonInfo")
public String toCteatePersonInfo() { // 跳轉(zhuǎn)新增頁面
return "/person/jPersonCreate";
}
@RequestMapping("/person/toUpdatePersonInfo")
public String toUpdatePersonInfo(Integer id, Model model) { // 跳轉(zhuǎn)修改頁面
Person p = ps.get(id); // 獲得要修改的記錄,重新設(shè)置頁面的值
model.addAttribute("p", p); // 將數(shù)據(jù)放到 response
return "/person/jPersonUpdate";
}
@RequestMapping("/person/updatePersonList")
public String updatePersonList(HttpServletRequest request, Person p, @RequestParam("photo") MultipartFile photeFile) throws IOException { // 更新人員信息
if (p.getId() == null) {
ps.insert(p); // 調(diào)用 Service 層方法宣虾,插入數(shù)據(jù)
} else {
String dir = request.getSession().getServletContext().getRealPath("/") + "/upload/";
String fileName = photeFile.getOriginalFilename(); // 原始的文件名
String extName = fileName.substring(fileName.lastIndexOf(".")); // 擴(kuò)展名
fileName = fileName.substring(0, fileName.lastIndexOf(".")) + System.nanoTime() + extName; // 防止文件名沖突
FileUtils.writeByteArrayToFile(new File(dir + fileName), photeFile.getBytes()); // 寫文件到 upload 目錄
p.setPhotoPath("/upload/" + fileName);
ps.update(p); // 調(diào)用 Service 層方法极谊,更新數(shù)據(jù)
}
return "redirect:/person/all.action"; // 轉(zhuǎn)向人員列表 action
}
@RequestMapping("/person/deleteById")
public String deleteById(Integer id) { // 刪除單條記錄
ps.deleteById(id);
return "redirect:/person/all.action"; // 轉(zhuǎn)向人員列表 action
}
@RequestMapping("/person/deleteMuch")
public String deleteMuch(String id) { // 批量刪除記錄
for (String delId : id.split(",")) {
ps.deleteById(Integer.parseInt(delId));
}
return "redirect:/person/all.action"; // 轉(zhuǎn)向人員列表 action
}
}
第三步:在 jPersonUpdate.jsp 中添加 Spring 框架的標(biāo)簽,并重新配置 form 表單
<%-- Created by IntelliJ IDEA. User: 維C果糖 Date: 2017/1/30 Time: 18:00 To change this template use File | Settings | File Templates. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>PersonList</title>
</head>
<body>
<!-- 其中安岂,modelAttribute 屬性用于接收設(shè)置在 Model 中的對象轻猖,必須設(shè)置,否則會報(bào) 500 的錯(cuò)誤 -->
<sf:form enctype="multipart/form-data" action="${pageContext.request.contextPath}/person/updatePersonList.action" modelAttribute="p" method="post">
<sf:hidden path="id"/>
<div style="padding:20px;">
修改人員信息
</div>
<table>
<tr>
<td>姓名:</td>
<td><sf:input path="name"/></td>
</tr>
<tr>
<td>年齡:</td>
<td><sf:input path="age"/></td>
</tr>
<tr>
<td>圖片:</td>
<td><input type="file" name="photo" value=""/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="btnOK" value="保存"/></td>
</tr>
</table>
</sf:form>
</body>
</html>
第四步:修改 jPersonList.jsp 頁面域那,添加頭像顯示欄
<%-- Created by IntelliJ IDEA. User: 維C果糖 Date: 2017/1/30 Time: 18:20 To change this template use File | Settings | File Templates. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>PersonList</title>
<script language="JavaScript"> /** * 批量提交方法 */ function deleteMuch() { document.forms[0].action = "${pageContext.request.contextPath}/person/deleteMuch.action"; document.forms[0].submit(); <!-- 手動提交 --> } </script>
</head>
<body>
<form method="post">
<div style="padding:20px;">
<h2>人員列表</h2>
</div>
<div style="padding-left:40px;padding-bottom: 10px;">
<a href="/springmvc-annotation/person/toCreatePersonInfo.action">新增</a> <!-- 跳轉(zhuǎn)路徑 -->
<a href="#" onclick="deleteMuch()">批量刪除</a> <!-- 調(diào)用 JavaScript -->
</div>
<table border="1">
<tr>
<td>選擇</td>
<td>頭像</td>
<td>編號</td>
<td>姓名</td>
<td>年齡</td>
<td>操作</td>
</tr>
<c:forEach items="${personList}" var="p">
<tr>
<td>
<input type="checkbox" name="id" value="${p.id}"/>
</td>
<td><img src="${pageContext.request.contextPath}${p.photoPath}"/></td>
<td>${p.id}</td>
<td>${p.name}</td>
<td>${p.age}</td>
<td>
<a href=/springmvc-annotation/person/toUpdatePersonInfo.action?id=${p.id}>修改</a>
<a href=/springmvc-annotation/person/deleteById.action?id=${p.id}>刪除</a>
</td>
</tr>
</c:forEach>
</table>
</form>
</body>
</html>
第五步:在 springmvc-servlet.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" 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 ">
<!-- 聲明注解開發(fā)方式 -->
<mvc:annotation-driven/>
<!-- 靜態(tài)資源的管理 -->
<mvc:resources location="/upload/" mapping="/upload/**"/>
<!-- 包自動掃描 -->
<context:component-scan base-package="spring.mvc.controller"/>
<!-- 內(nèi)部資源視圖解析器咙边,前綴 + 邏輯名 + 后綴 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 文件上傳視圖解析器,其名字必須為 multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/> <!-- 限制頁面上傳文件最大為 10M -->
</bean>
</beans>
在完成以上步驟后次员,啟動 tomcat 服務(wù)器败许,然后訪問 http://localhost:8080/springmvc-annotation/person/all.action,頁面如下所示:
然后淑蔚,以編號為 0 的記錄為例市殷,進(jìn)行測試,點(diǎn)擊“修改”刹衫,頁面如下所示:
接下來醋寝,點(diǎn)擊“選擇文件”搞挣,進(jìn)而選擇咱們想要設(shè)置為頭像的圖片,點(diǎn)擊“保存”音羞,頁面如下所示:
至此囱桨,圖像的上傳及顯示功能,全部實(shí)現(xiàn)成功嗅绰。