前言
最近很多人反映,當spring+springmvc+mybatis整合之後,不知道圖片的上傳、回顯、展示、下載如何實現。其實ssm框架已經幫我們封裝好了這塊,我們要做的就是進行相關的配置和調用。今天我就配置這塊進行一個簡單講解。
SSM框架整合可參考:https://blog.csdn.net/guigu2012/article/details/72926481。
1、導入jar包
如果是maven工程,只需要在pom.xml添加如下代碼:
<!-- 上傳下載需要設計到的jar包 -->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
2、編寫工具類
package com.yueqian.ssm.common;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
/**
* 圖片工具類
* @author gzlx
*
*/
public class ImageUtils {
/**
* 上傳圖片
* @param request
* @param book
* @param pictureFile
* @throws IOException
*/
public static String upload(HttpServletRequest request,
MultipartFile pictureFile) throws IOException {
String imgPath = null;//裝配後的圖片地址
//上傳圖片
if(pictureFile!=null&&!pictureFile.isEmpty()){
// 使用UUID給圖片重命名,並去掉四個“-”
String name = UUID.randomUUID().toString().replaceAll("-", "");
// 獲取文件的擴展名
String ext = FilenameUtils.getExtension(pictureFile
.getOriginalFilename());
// 設置圖片上傳路徑
String url = request.getSession().getServletContext()
.getRealPath("/upload");
// 檢驗文件夾是否存在
isFolderExists(url);
// 以絕對路徑保存重名命後的圖片
pictureFile.transferTo(new File(url + "/" + name + "." + ext));
// 裝配圖片地址
imgPath = "upload/" + name + "." + ext;
}
return imgPath;
}
/**
* 驗證文件夾是否存在
* @param strFolder
* @return
*/
public static boolean isFolderExists(String strFolder){
File file = new File(strFolder);
if (!file.exists())
{
if (file.mkdir())
{
return true;
}
else{
return false;
}
}
System.out.println("-----------------文件上傳路徑:"+strFolder);
return true;
}
/**
* 獲取目錄下所有文件(按時間排序)
* @param path
* @return
*/
public static List<File> getFileSort(String path) {
List<File> list = getFiles(path, new ArrayList<File>());
if (list != null && list.size() > 0) {
Collections.sort(list, new Comparator<File>() {
public int compare(File file, File newFile) {
if (file.lastModified() < newFile.lastModified()) {//降序<;升序>
return 1;
} else if (file.lastModified() == newFile.lastModified()) {
return 0;
} else {
return -1;
}
}
});
}
return list;
}
/**
* 獲取目錄下所有文件
* @param realpath
* @param files
* @return
*/
public static List<File> getFiles(String realpath, List<File> files) {
File realFile = new File(realpath);
if (realFile.isDirectory()) {
File[] subfiles = realFile.listFiles();
for (File file : subfiles) {
if (file.isDirectory()) {
getFiles(file.getAbsolutePath(), files);
} else {
files.add(file);
}
}
}
return files;
}
}
3、文件上傳
3.1 修改spirngmvc.xml文件
<!-- 定義文件上傳解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設定默認編碼 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 設定文件上傳的最大值5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
<!-- 其他的大家可以自行配置,不影響主功能-->
</bean>
3.2 修改jsp界面
上傳圖片的<input>標籤中,name屬性的名字和實體bean的屬性名稱不能一致,同時form表單加enctype屬性:
注意:form表單中可以同時放置普通的表單數據
<form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/addUser.do" >
<input type="file" name="pictureFile" id="pictureFile" value="請選擇圖片" />
3.3 在Controller中編寫相關的代碼
/**
* 添加用戶信息
* @param user,封裝表單中除圖片地址以外的其他數據(要求<input>中的name跟實體類中的屬性一致)
* @param request,用來獲取文件的存儲位置等
* @param pictureFile,封裝上傳圖片的信息如大小、文件名、擴展名等,(要求<input>中的name跟次命名一致)。
* @return
* 注意:圖片提交input輸入框的name屬性值要與Controller中MultipartFile
* 接口所聲明的形參名一致,不然需要用@RequestParam註解綁定
*/
@RequestMapping(path = "/addUser.do", method = RequestMethod.POST)
public String addUser(User user, HttpServletRequest request, MultipartFile pictureFile) {
// 得到上傳圖片的地址
String imgPath;
try {
//ImageUtils爲之前添加的工具類
imgPath = ImageUtils.upload(request, pictureFile);
if (imgPath != null) {
// 將上傳圖片的地址封裝到實體類
user.setPic(imgPath);
System.out.println("-----------------圖片上傳成功!");
}else{
System.out.println("-----------------圖片上傳失敗!");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("----------------圖片上傳失敗!");
}
//將數據提交到數據庫(包含文件和普通表單數據)
int rowNo = userService.saveUser(user);
if (rowNo > 0) {
System.out.println("----------------------用戶添加成功!");
// 轉發:forword,重定向:redirect
return "redirect:/user/findUsers.do";
} else {
System.out.println("----------------------用戶添加失敗!");
return "addUser";
}
}
4、圖片回顯
在jsp界面顯示圖片的<img>標籤中,通過el表達式來動態給src賦值
<!--${book.pic}數據庫中存儲的:upload/圖片名稱.圖片後綴-->
<img src="${pageContext.request.contextPath}/${book.pic }"/>
以上內容爲圖片【其他文件等同】的上傳以及圖片的回顯,
5、獲取本地文件,並通過jsp進行展示
5.1 在Controller中編寫相關代碼
/**
* 文件列表的顯示
* @param request
* @param m:封裝數據,這裏主要是封裝List<File>
* @return
*/
@RequestMapping(value = "/showFile.do")
public String showFile(HttpServletRequest request, Model m) {
ServletContext servletContext = request.getServletContext();
//動態獲取存放文件的本地路徑【絕對路徑】
String path = servletContext.getRealPath("/upload");
//獲取文件夾下的所有文件【ImageUtils爲之前編寫的工具類】
//File[] fileList = new File(path).listFiles();//原生寫法
List<File> fileList = ImageUtils.getFileSort(path);
m.addAttribute("fileList", fileList);
return "showFile";
}
5.2 通過jsp進行文件展示
showFile.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<h3 align="center">文件列表展示</h3>
<c:choose>
<c:when test="${not empty fileList }">
<!--索引-->
<c:set var="index" value='1'></c:set>
<c:forEach items="${fileList }" var="file">
<!-- filename:文件的名字,不帶UUID -->
<c:set var="filename"
value='${fn:substring(file.name,fn:indexOf(file.name,"_")+1,fn:length(file.name)) }' ></c:set>
<!-- filefullname:文件的名字,帶UUID c:set中使用“\\”會報錯,要使用“\\\\”,其他地方使用“\\”即可-->
<c:set var="filefullname"
value='${fn:split(file.path,"\\\\")[fn:length(fn:split(file.path,"\\\\"))-1] }'></c:set>
<!-- rootdir:文件的目錄 -->
<c:set var="rootdir"
value='${pageContext.request.contextPath}/upload/'></c:set>
<div>
<img alt='${filefullname}' src='${rootdir.concat(filefullname) }' style="width: 160px;height: 100px;border-radius: 5px;"/>
<!-- 文件的全路徑 -->
<a href="${pageContext.request.contextPath}/user/fileDownload.do?fileName=${filefullname}">下載</a>
</div>
<!-- 每行顯示5張圖片 -->
<c:if test="${index%5==0 }">
<br>
</c:if>
<!--索引+1-->
<c:set var="index" value='${index+1 }'></c:set>
</c:forEach>
</c:when>
<c:otherwise>
暫無數據
</c:otherwise>
</c:choose>
</body>
</html>
6、文件下載
在jsp中,通過<a ></a>標籤綁定下載文件的路徑,見上文5.2所示
6.1 在Controller中編寫相關代碼
/**
* 文件下載
* 用ResponseEntity<byte[]> 返回值完成文件下載
* @param request
* @param fileName:文件的名稱
* @return
* @throws Exception
*/
@RequestMapping(value = "fileDownload.do")
public ResponseEntity<byte[]> fileDownload(HttpServletRequest request, @RequestParam(value = "fileName") String fileName)
throws Exception {
String fName = fileName.substring(fileName.lastIndexOf("_") + 1); // 從uuid_name.jpg中截取文件名
//根據文件的絕對路徑,獲取文件
File file = new File(request.getServletContext().getRealPath("/upload/"+fName));
//設置請求頭
HttpHeaders headers = new HttpHeaders();
fileName = new String(fileName.getBytes("utf-8"), "iso8859-1");
headers.add("Content-Disposition", "attachment;filename=" + fileName);
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, statusCode);
return response;
}
到此,整個圖片上傳、回顯、展示、下載就全部完成了,希望能夠幫助到各位朋友!