目錄
1、使用場景
2、代碼實作
2.1、引入pom.xml jar包
2.2、實作代碼
3、成果展現
4、總結
1、使用場景
我們經常會在開發之中遇見要求上傳檔案,特别是後端接口開發過程之中。比如有一下場景:
(1)、我們每個人都需要上傳頭像
(2)、軟體App或者PC端需要針對問題回報需要上傳兩張回報截圖
(3)、還有相關論壇或者問題可能需要上傳圖檔等操作。
以前我們項目之中主要都是通過 Ftp方式上傳問題圖檔,使用封裝的Java後端代碼;但是我們可能實際開發之中可能就要求直接使用Http上傳檔案圖檔。并且我是遇到一個場景,我們原來業務系統使用的Ftp上傳的檔案;結果在部署伺服器不開放對應端口;于是要求使用Http上傳檔案圖檔。最後因為工期比較緊張;此功能暫時屏蔽啦。于是本文在以前發生的親身經曆需要使用Http方式上傳問題内容。
2、代碼實作
2.1、引入pom.xml jar包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
2.2、實作代碼
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
/**
* @Classname RequestGetFileInputStream
* @Description 針對上傳檔案的相關操作 使用http request方式
* @Date 2019/11/8 18:29
* @Created by jianxiapc
*/
public class UploadFileCommonUtil {
private static Logger logger = LoggerFactory.getLogger(UploadFileCommonUtil.class);
/**
* 通過request之中獲得file的Parts 實作檔案的 上傳
* @param request
* @param response
* @param uploadFileDirPath
* @param frontEndFileInputName
* @param renameFileName
* @throws IOException
* @throws ServletException
*/
public static String uploadFileByPartsHttpServletRequest(HttpServletRequest request, HttpServletResponse response,
String uploadFileDirPath, String frontEndFileInputName,String renameFileName) throws IOException, ServletException {
logger.info("request.getContentType(): " + request.getContentType());
if (!request.getContentType().split(";")[0].equals("multipart/form-data")){
return null;
}
Collection<Part> parts = request.getParts();
/**
for(Part part:parts){
System.out.println(part);
String uploadFileDirPath="";
}
*/
String uploadFileWholeDirPath="";
for (Iterator<Part> iterator = parts.iterator(); iterator.hasNext(); ) {
Part part = iterator.next();
logger.info("-----類型名稱------->" + part.getName());
logger.info("-----類型------->" + part.getContentType());
logger.info("-----送出的類型名稱------->" + part.getSubmittedFileName());
logger.info("----流-------->" + part.getInputStream());
uploadFileWholeDirPath= uploadFileProcess(part, uploadFileDirPath, frontEndFileInputName,renameFileName);
}
return uploadFileWholeDirPath;
}
/**
* 通過MultipartHttpServletRequest 實作檔案的上傳
* @param request
* @param response
* @param uploadFileDirPath
* @param frontEndFileInputName
* @param renameFileName
* @return
* @throws IOException
*/
public static String uploadFileByMultipartHttpServletRequest(HttpServletRequest request, HttpServletResponse response,
String uploadFileDirPath, String frontEndFileInputName,String renameFileName) throws IOException {
//将目前上下文初始化給 CommonsMutipartResolver (多部分解析器)
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
String uploadFileWholeDirPath="";
// 判斷是否是多資料段送出格式
if (multipartResolver.isMultipart(request)) {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator<String> iter = multiRequest.getFileNames();
logger.info("iter.hasNext(): " + iter.hasNext());
Integer fileCount = 0;
//檔案流
FileOutputStream fileOutputStream = null;
while (iter.hasNext()) {
MultipartFile multipartFile = multiRequest.getFile(iter.next());
String fileName = multipartFile.getOriginalFilename();
logger.info("upload filename: " + fileName);
if (fileName == null || fileName.trim().equals("")) {
continue;
}
//20170207 針對IE環境下filename是整個檔案路徑的情況而做以下處理
Integer index = fileName.lastIndexOf("\\");
String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
String newStr = "";
if (index > -1) {
newStr = fileName.substring(index + 1);
} else {
newStr = fileName;
}
if (!newStr.equals("")) {
fileName = newStr;
}
logger.info("new filename: " + fileName);
if (multipartFile != null) {
if(null!=renameFileName&&!"".equals(renameFileName)){
uploadFileWholeDirPath=uploadFileDirPath+renameFileName+ext;
}else{
uploadFileWholeDirPath=uploadFileDirPath+fileName;
}
File storageFile = new File(uploadFileWholeDirPath);
if(!storageFile.getParentFile().exists()){
storageFile.getParentFile().mkdirs();
}
//擷取輸出流
OutputStream os=new FileOutputStream(uploadFileWholeDirPath);
//擷取輸入流 CommonsMultipartFile 中可以直接得到檔案的流
InputStream is=multipartFile.getInputStream();
int temp;
//一個一個位元組的讀取并寫入
while((temp=is.read())!=(-1))
{
os.write(temp);
}
os.flush();
os.close();
is.close();
}
}
}
return uploadFileWholeDirPath;
}
/**
* 上傳檔案的處理函數
* @param part
* @param uploadFileDirPath
* @param frontEndFileInputName
* @param renameFileName 是否需要重新命名檔案名稱
* @return
* @throws IOException
*/
private static String uploadFileProcess(Part part, String uploadFileDirPath, String frontEndFileInputName,String renameFileName) throws IOException {
String uploadFileWholeDirPath="";
if (part.getName().equals(frontEndFileInputName)) {
String cd = part.getHeader("Content-Disposition");
String[] cds = cd.split(";");
String filename = cds[2].substring(cds[2].indexOf("=") + 1).substring(cds[2].lastIndexOf("//") + 1).replace("\"", "");
String ext = filename.substring(filename.lastIndexOf(".") + 1);
logger.info("filename:" + filename);
logger.info("ext:" + ext);
InputStream is = part.getInputStream();
if (Arrays.binarySearch(ImageIO.getReaderFormatNames(), ext) >= 0)
uploadImageProcess(uploadFileDirPath, filename, ext, is);
else {
uploadCommonFileProcess(uploadFileDirPath, filename, is);
}
if(null!=renameFileName&&!"".equals(renameFileName)){
uploadFileWholeDirPath=uploadFileDirPath+renameFileName+ext;
}else{
uploadFileWholeDirPath=uploadFileDirPath+filename;
}
}
return uploadFileWholeDirPath;
}
/**
* 通用檔案上傳處理
*
* @param uploadFileDirPath
* @param filename
* @param is
*/
private static void uploadCommonFileProcess(String uploadFileDirPath, String filename, InputStream is) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(uploadFileDirPath + filename));
int b = 0;
while ((b = is.read()) != -1) {
fos.write(b);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 圖檔檔案上傳處理
*
* @param uploadFileDirPath
* @param filename
* @param ext
* @param is
* @throws IOException
*/
public static void uploadImageProcess(String uploadFileDirPath, String filename, String ext, InputStream is) throws IOException {
Iterator<ImageReader> irs = ImageIO.getImageReadersByFormatName(ext);
ImageReader ir = irs.hasNext() ? irs.next() : null;
if (ir == null)
return;
//必須轉換為ImageInputStream,否則異常
ir.setInput(ImageIO.createImageInputStream(is));
ImageReadParam rp = ir.getDefaultReadParam();
Rectangle rect = new Rectangle(0, 0, 200, 200);
rp.setSourceRegion(rect);
//allowSearch必須為true,否則有些圖檔格式imageNum為-1。
int imageNum = ir.getNumImages(true);
logger.info("imageNum:" + imageNum);
for (int imageIndex = 0; imageIndex < imageNum; imageIndex++) {
BufferedImage bi = ir.read(imageIndex, rp);
ImageIO.write(bi, ext, new File(uploadFileDirPath + filename));
}
}
}
import org.spring.springboot.excel.poi.export.utils.annotation.FileStorageProperties;
import org.spring.springboot.excel.poi.export.utils.common.UploadFileCommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Classname UploadFileController
* @Description 基本的檔案上傳實作測試
* @Date 2019/11/9 11:42
* @Created by jianxiapc
*/
@RestController
public class UploadFileController {
@Autowired
private FileStorageProperties fileStorageProperties;
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadFile(HttpServletRequest request, HttpServletResponse response, @RequestParam("importExelFile") MultipartFile file) throws Exception {
String uploadFileDirPath =fileStorageProperties.getUploadDir();
//String storageFilePath=UploadFileCommonUtil.uploadFileByPartsHttpServletRequest(request,response,uploadFileDirPath,"importExelFile",null);
String storageFilePath=UploadFileCommonUtil.uploadFileByMultipartHttpServletRequest(request,response,uploadFileDirPath,"importExelFile",null);
return storageFilePath;
}
}
3、成果展現
4、總結
通過本文章可以實作了基本檔案通過HttpRequest方式上傳檔案的實作。
本人源碼所在位址: 源碼位址:https://github.com/jianxia612/springboot-excel-import-export-fileupload.git