SpringBoot文件上传与POI的使用
1.使用springboot上传文件
本文所要源码在一个项目中,源码:https://github.com/zhongyushi-git/springboot-upload-download.git。下面的介绍与源码可能有差别,以源码为准!
1.1环境准备
1)新建一个springboot的项目
2)导入web坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
1.2实战演练
1)创建文件的工具类,在类中添加一个上传的方法
/**
* @author zhongyushi
* @date 2020/9/29 0029
* @dec 文件工具类,用于上传和下载
*/
public class FileUtil {
//文件保存的路径
private static final String STORE_PATH = "D://files"; public static String uploadFile(MultipartFile file) {
//设置日期的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
//设置文件的保存路径是项目运行目录下的uploadFile目录下
String realPath = new File(STORE_PATH).getAbsolutePath();
//通过日期 对文件归类,如2019/11/30,2019/11/29
String format = File.separator + sdf.format(new Date());
format = format.replace("/", "\\");
//根据规则创建目录
File folder = new File(realPath + format);
if (!folder.isDirectory()) {
folder.mkdirs();
}
//获取文件的原始名
String oldName = file.getOriginalFilename();
//获取文件的后缀名
String suffix = oldName.substring(oldName.lastIndexOf("."));
//使用uuid设置新的文件名,防止文件名重复
String newName = UUID.randomUUID().toString() + suffix;
try {
//文件保存
file.transferTo(new File(folder, newName));
//生成文件的保存路径
String accessPath = realPath + format + File.separator + newName;
return accessPath;
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
}
}
2)创建文件上传的接口upload
package com.zys.springbootuploaddownload; import com.zys.springbootuploaddownload.util.FileUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream; /**
* @author zhongyushi
* @date 2020/9/29 0029
* @dec 上传下载的接口
*/
@RestController
public class TestController { /**
* 文件上传,返回文件保存路径
* @param file
* @return
*/
@PostMapping("/upload")
public String uploadFile(MultipartFile file){
String path = FileUtil.uploadFile(file);
return path;
}
}
3)在资源目录的static目录下创建一个文件上传的页面upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" value="选择文件">
<input type="submit" value="上传">
</form>
</body>
</html>
注意:按照上面的写法,页面中type是file的name值必须和后台得参数值相同,否则会出现空指针异常。
4)测试
启动项目,在浏览器输入http://localhost:8080/upload.html,选择文件上传,上传成功时会返回文件保存的位置,此时在指定的目录下会生成多级的目录,最后一级是文件。
2.通过浏览器下载文件
1)在文件的工具类添加两个方法
/**
* 指定路径下载文件
* @param path 文件路径
* @param filename 文件名,带后缀
* @param response
* @throws IOException
*/
public static void downloadFile(String path, String filename, HttpServletResponse response) throws IOException {
File file = new File(path + File.separator + filename);
if (!file.exists()) {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("error");
return;
}
FileInputStream in = new FileInputStream(file);
downloadFile(filename, in, response);
} /**
* 通过流下载文件
*
* @param filename 文件名,带后缀
* @param in 输入流
* @param response
* @throws IOException
*/
public static void downloadFile(String filename, InputStream in, HttpServletResponse response) throws IOException {
//设置浏览器直接下载文件,不打开,并设置文件名的编码
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
int len = 0;
byte bytes[] = new byte[1024];
OutputStream out = response.getOutputStream();
while ((len = in.read(bytes)) > 0) {
out.write(bytes, 0, len);
}
in.close();
}
2)添加读取资源目录的工具类
package com.zys.springbootuploaddownload.util; import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream; /**
* @author zhongyushi
* @date 2020/9/29 0029
* @dec 根据路径获取文件流
*/
@Component
public class GetFileStream { /**
* 获取资源目录下的文件流
*
* @param path 文件路径
* @param fileName 文件名,带后缀
* @return
*/
public InputStream getResourceStream(String path, String fileName) throws FileNotFoundException {
InputStream stream = this.getClass().getClassLoader().getResourceAsStream(path + File.separator + fileName);
if (stream == null) {
throw new FileNotFoundException("路径错误,未找到指定文件");
}
return stream;
} }
3)在上传的接口添加下载的方法。需要使用@Autowired注入GetFileStream
/**
* 从本地下载文件
* @param response
* @throws IOException
*/
@GetMapping("/download1")
public void download1(HttpServletResponse response) throws IOException {
String path = "D:\\files";
String fileName="123.txt";
FileUtil.downloadFile(path,fileName,response);
} /**
* 从资源目录下载文件
* @param response
* @throws IOException
*/
@GetMapping("/download2")
public void download2(HttpServletResponse response) throws IOException {
String path = "templates";
String fileName="a.txt";
InputStream stream = getFileStream.getResourceStream(path, fileName);
FileUtil.downloadFile(fileName,stream,response);
}
这里有两个方法,一个是直接下载指定路径下的文件,另一个是下载服务器上资源目录下的文件。
3)在static目录下新建文件下载页面file.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="/download1">下载本地文件</a>
<a href="/download2">下载服务器文件</a>
</body>
</html>
4)测试
启动项目,在浏览器输入http://localhost:8080/file.html,点击下载即可下载文件。下载之前,代码中指定的文件需要存在对应的位置,否则会下载失败,文件的路径可自定义。
3.poi实现文件导入
3.1环境准备
1)导入poi的依赖
<!-- POI,excel解析相关 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
2)导入mysql等相关的依赖,配置数据库信息(详见源码)
3)在数据库执行sql脚本。脚本在项目根目录下。
4)导入必需的工具类
package com.zys.springbootuploaddownload.util; import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; /**
* 读取.properties配置文件的内容至Map中
*/
public class PropertiesUtil { /**
* 读取.properties配置文件的内容至Map
*
* @param propertiesFile
* @return
* @throws IOException
*/
public static Map read(String propertiesFile) throws Exception {
try {
if (!(propertiesFile.indexOf("properties") > 0)) {
propertiesFile = propertiesFile + ".properties";
}
InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(propertiesFile);
Properties p = new Properties();
p.load(inStream); Map<Object, Object> map = properties2map(p);
return map;
} catch (IOException e) {
throw new Exception(e);
}
} /**
* 将属性文件转为map
*
* @param prop
* @return
*/
public static Map properties2map(Properties prop) {
Map<Object, Object> map = new HashMap<Object, Object>();
Enumeration enu = prop.keys();
while (enu.hasMoreElements()) {
Object obj = enu.nextElement();
Object objv = prop.get(obj);
map.put(obj, objv);
}
return map;
} public static Map<String,String> getKeyAndValue(String fileName,String configName) throws Exception {
Map<String,String> keyMap=new HashMap<>();
Map<String, String> map = PropertiesUtil.read("importConfig.properties");
//过滤文件内容,只截取student的配置
for (String key : map.keySet()) {
if (key.startsWith("student.")) {
String[] split = key.split("student.");
keyMap.put(map.get(key), split[1]);
}
}
return keyMap;
}
}
此工具类用来读取指定的配置文件的内容。
package com.zys.springbootuploaddownload.util; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zys.springbootuploaddownload.entity.ExcelData;
import com.zys.springbootuploaddownload.entity.Student;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*; /**
* @Author: yushizhong
* @Date: 2020/2/22 12:07
* @Title: 解析excel内容+导出excel
* 解析excel:调用readExcel方法
* 导出excel:浏览器下载调用exportExcel方法
* 本地下载调用generateExcel方法
*/
public class ExcelUtil { public final static String XLSX = ".xlsx";
public final static String XLS = ".xls"; /**
* 获取Excel文件(.xls和.xlsx都支持)
*
* @param path 文件全路径
* @return 解析excle后的Json数据
*/
public static JSONArray readExcel(String path, Map<String, String> myMap) throws Exception {
File file = new File(path);
int res = checkFile(file);
if (res == 0) {
System.out.println("File not found");
} else if (res == 1) {
return readXLSX(file, myMap);
} else if (res == 2) {
return readXLS(file, myMap);
}
JSONArray array = new JSONArray();
return array;
} /**
* 判断File文件的类型
*
* @param file 传入的文件
* @return 0-文件为空,1-XLSX文件,2-XLS文件,3-其他文件
*/
public static int checkFile(File file) {
if (file == null) {
return 0;
}
String fileName = file.getName();
if (fileName.endsWith(XLSX)) {
return 1;
}
if (fileName.endsWith(XLS)) {
return 2;
}
return 3;
} /**
* 读取XLSX文件
*
* @param file
* @return
* @throws IOException
* @throws InvalidFormatException
*/
public static JSONArray readXLSX(File file, Map<String, String> myMap) throws IOException, InvalidFormatException {
Workbook book = new XSSFWorkbook(file);
//只读第一个sheet表内容
Sheet sheet = book.getSheetAt(0);
return read(sheet, book, myMap);
} /**
* 读取XLS文件
*
* @param file 文件对象
* @throws IOException
* @throws FileNotFoundException
*/
public static JSONArray readXLS(File file, Map<String, String> myMap) throws FileNotFoundException, IOException {
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file));
Workbook book = new HSSFWorkbook(poifsFileSystem);
//只读第一个sheet表内容
Sheet sheet = book.getSheetAt(0);
return read(sheet, book, myMap);
} /**
* 解析数据
*
* @param sheet 表格sheet对象
* @param book 用于流关闭
* @param myMap excel列名替换的值
* @return
* @throws IOException
*/
public static JSONArray read(Sheet sheet, Workbook book, Map<String, String> myMap) throws IOException {
int rowStart = sheet.getFirstRowNum(); // 首行下标
int rowEnd = sheet.getLastRowNum(); // 尾行下标
// 如果首行与尾行相同,表明只有一行,直接返回空数组
if (rowStart == rowEnd) {
book.close();
return new JSONArray();
}
// 获取第一行JSON对象键
Row firstRow = sheet.getRow(rowStart);
int cellStart = firstRow.getFirstCellNum();
int cellEnd = firstRow.getLastCellNum();
Map<Integer, String> keyMap = new HashMap<Integer, String>();
for (int j = cellStart; j < cellEnd; j++) {
keyMap.put(j, getValue(firstRow.getCell(j), rowStart, j, book, true));
}
keyMap = replaceKey(keyMap, myMap);
// 获取每行JSON对象的值
JSONArray array = new JSONArray();
for (int i = rowStart + 1; i <= rowEnd; i++) {
Row eachRow = sheet.getRow(i);
JSONObject obj = new JSONObject();
StringBuffer sb = new StringBuffer();
for (int k = cellStart; k < cellEnd; k++) {
if (eachRow != null) {
String val = getValue(eachRow.getCell(k), i, k, book, false);
sb.append(val); // 所有数据添加到里面,用于判断该行是否为空
obj.put(keyMap.get(k), val);
}
}
if (sb.toString().length() > 0) {
array.add(obj);
}
}
book.close();
return array;
} /**
* 获取每个单元格的数据
*
* @param cell 单元格对象
* @param rowNum 第几行
* @param index 该行第几个
* @param book 主要用于关闭流
* @param isKey 是否为键:true-是,false-不是。 如果解析Json键,值为空时报错;如果不是Json键,值为空不报错
* @return
* @throws IOException
*/
public static String getValue(Cell cell, int rowNum, int index, Workbook book, boolean isKey) throws IOException {
// 空白或空
if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
if (isKey) {
book.close();
throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum, ++index));
} else {
return "";
}
}
// 0. 数字 类型
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return df.format(date);
}
//防止当作数字而导致最后的0丢失
DecimalFormat df = new DecimalFormat("0");
String val = df.format(cell.getNumericCellValue());
val = val.toUpperCase();
if (val.contains("E")) {
val = val.split("E")[0].replace(".", "");
}
return val;
}
// 1. String类型
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
String val = cell.getStringCellValue();
if (val == null || val.trim().length() == 0) {
if (book != null) {
book.close();
}
return "";
}
return val.trim();
}
// 2. 公式 CELL_TYPE_FORMULA
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
return cell.getStringCellValue();
}
// 4. 布尔值 CELL_TYPE_BOOLEAN
if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return cell.getBooleanCellValue() + "";
}
// 5. 错误 CELL_TYPE_ERROR
return "";
} /**
* 替换读取的数据key
*
* @param oldMap 原始map
* @param myMap 要替换的value map
* @return
*/
public static Map<Integer, String> replaceKey(Map<Integer, String> oldMap, Map<String, String> myMap) {
Map<Integer, String> newMap = new HashMap<>();
int size = myMap.size();
if (oldMap.size() != size) {
throw new NullPointerException("表格内容无法识别,请检查内容的规范性!");
} else {
for (Integer key : oldMap.keySet()) {
for (String key2 : myMap.keySet()) {
if (oldMap.get(key).equals(key2)) {
newMap.put(key, myMap.get(key2));
}
}
}
}
return newMap;
} public static void exportExcel(String sheetName, Map<String, String> keyMap, String fileName, List<Map> list, HttpServletResponse response) throws Exception { } /**
* 使用浏览器选下载
*
* @param response
* @param fileName 下载时的文件名
* @param data
* @throws Exception
*/
public static void exportExcel(HttpServletResponse response, String fileName, ExcelData data) throws Exception {
// 告诉浏览器用什么软件可以打开此文件
response.setHeader("content-Type", "application/vnd.ms-excel");
// 下载文件的默认名称
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "utf-8"));
exportExcel(data, response.getOutputStream());
} /**
* 本地下载
*
* @param excelData
* @param path 文件要存储的路径
* @return
* @throws Exception
*/
public static int generateExcel(ExcelData excelData, String path) throws Exception {
File f = new File(path);
FileOutputStream out = new FileOutputStream(f);
return exportExcel(excelData, out);
} /**
* 创建excel表
*
* @param data
* @param out
* @return
* @throws Exception
*/
private static int exportExcel(ExcelData data, OutputStream out) throws Exception {
XSSFWorkbook wb = new XSSFWorkbook();
int rowIndex = 0;
try {
//设置工作表的名字
String sheetName = data.getName();
if (null == sheetName) {
sheetName = "Sheet1";
}
//创建工作表
XSSFSheet sheet = wb.createSheet(sheetName);
rowIndex = writeExcel(wb, sheet, data);
wb.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
//此处需要关闭 wb 变量
out.close();
}
return rowIndex;
} /**
* 设置表显示字段
*
* @param wb
* @param sheet
* @param data
* @return
*/
private static int writeExcel(XSSFWorkbook wb, Sheet sheet, ExcelData data) {
int rowIndex = 0;
rowIndex = writeTitlesToExcel(wb, sheet, data.getTitles());
rowIndex = writeRowsToExcel(wb, sheet, data.getRows(), rowIndex);
autoSizeColumns(sheet, data.getTitles().size() + 1);
return rowIndex;
} /**
* 设置表头
*
* @param wb
* @param sheet
* @param titles
* @return
*/
private static int writeTitlesToExcel(XSSFWorkbook wb, Sheet sheet, List<String> titles) {
int rowIndex = 0;
int colIndex = 0;
Font titleFont = wb.createFont();
//设置字体
titleFont.setFontName("宋体");
//设置字号
titleFont.setFontHeightInPoints((short) 12);
//设置颜色
titleFont.setColor(IndexedColors.BLACK.index);
XSSFCellStyle titleStyle = wb.createCellStyle();
titleStyle.setFont(titleFont);
setBorder(titleStyle, BorderStyle.THIN);
Row titleRow = sheet.createRow(rowIndex);
titleRow.setHeightInPoints(25);
colIndex = 0;
for (String field : titles) {
Cell cell = titleRow.createCell(colIndex);
cell.setCellValue(field);
cell.setCellStyle(titleStyle);
colIndex++;
}
rowIndex++;
return rowIndex;
} /**
* 设置内容
*
* @param wb
* @param sheet
* @param rows
* @param rowIndex
* @return
*/
private static int writeRowsToExcel(XSSFWorkbook wb, Sheet sheet, List<List<Object>> rows, int rowIndex) {
int colIndex;
Font dataFont = wb.createFont();
dataFont.setFontName("宋体");
dataFont.setFontHeightInPoints((short) 12);
dataFont.setColor(IndexedColors.BLACK.index);
XSSFCellStyle dataStyle = wb.createCellStyle();
dataStyle.setFont(dataFont);
setBorder(dataStyle, BorderStyle.THIN);
for (List<Object> rowData : rows) {
Row dataRow = sheet.createRow(rowIndex);
dataRow.setHeightInPoints(25);
colIndex = 0;
for (Object cellData : rowData) {
Cell cell = dataRow.createCell(colIndex);
if (cellData != null) {
cell.setCellValue(cellData.toString());
} else {
cell.setCellValue("");
}
cell.setCellStyle(dataStyle);
colIndex++;
}
rowIndex++;
}
return rowIndex;
} /**
* 自动调整列宽
*
* @param sheet
* @param columnNumber
*/
private static void autoSizeColumns(Sheet sheet, int columnNumber) {
for (int i = 0; i < columnNumber; i++) {
int orgWidth = sheet.getColumnWidth(i);
sheet.autoSizeColumn(i, true);
int newWidth = (int) (sheet.getColumnWidth(i) + 100);
if (newWidth > orgWidth) {
sheet.setColumnWidth(i, newWidth);
} else {
sheet.setColumnWidth(i, orgWidth);
}
}
} /**
* 设置边框
*
* @param style
* @param border
*/
private static void setBorder(XSSFCellStyle style, BorderStyle border) {
style.setBorderTop(border);
style.setBorderLeft(border);
style.setBorderRight(border);
style.setBorderBottom(border);
} }
此工具类是用来解析excel内容以及导出excel。
3.2实战演练
1)编写导入接口
@PostMapping("/import")
public JSONObject importExcel(MultipartFile file) {
JSONObject jsonObject = new JSONObject();
try {
//获取配置文件的内容
Map<String, String> keyMap = PropertiesUtil.getKeyAndValue(importConfigName, "student.");
//上传文件
String path = FileUtil.uploadFile(file, uploadPath);
//读取上传的文件内容
JSONArray jsonArray = ExcelUtil.readExcel(path, keyMap);
int count = studentService.importExcel(jsonArray);
if (count >= 0) {
jsonObject.put("status", true);
jsonObject.put("msg", "学生信息导入成功");
} else {
jsonObject.put("status", false);
jsonObject.put("msg", "学生信息导入失败");
}
} catch (Exception e) {
log.info("=====学生信息导入发生异常=====" + e.getMessage());
jsonObject.put("status", false);
jsonObject.put("msg", "学生信息导入失败");
}
return jsonObject;
}
2)编写导入的实体类、service及dao(见源码)。
3)把资源目录下templates目录下的excel文件复制一份,加入相关的数据
4)在资源目录新建导入的配置文件importConfig.properties,内容如下
#文件的读取和导入相关基础配置 #student相关配置,名字必须叫student,下面同
student.name=姓名
student.sno=学号
student.sex=性别
student.phone=手机号
5)添加导入的页面import.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>导入导出excel</title>
</head>
<body>
<div>
<a href="/download2">下载模板</a>
</div>
<form action="/import" method="post" enctype="multipart/form-data">
<input type="file" name="file" value="选择文件">
<input type="submit" value="导入">
</form> </body>
</html>
6)测试。访问http://localhost:8080/import.html,点击导入,选择编辑好的excel,然后导入,会返回导入成功的信息,查看数据库,数据已被导入进来了。
4.poi实现文件导出
1)添加导出的接口
@GetMapping("/export")
public void exportExcel(HttpServletResponse response) throws Exception {
List<Student> list = studentService.queryList(); ExcelData data = new ExcelData();
String fileName = "学生信息表";
//设置工作表名称
data.setName(fileName);
//设置表头
List<String> titles = new ArrayList();
titles.add("姓名");
titles.add("学号");
titles.add("性别");
titles.add("手机号");
data.setTitles(titles);
//设置数据内容
List<List<Object>> rows = new ArrayList();
for (Student stu : list) {
List<Object> row = new ArrayList();
row.add(stu.getName());
row.add(stu.getSno());
row.add(stu.getSex());
row.add(stu.getPhone());
rows.add(row);
}
data.setRows(rows);
try {
String formatName = new SimpleDateFormat("HHmmss").format(new Date());
ExcelUtil.exportExcel(response, fileName + formatName, data);
} catch (Exception e) {
log.info("=====学生信息导出发生异常=====" + e.getMessage());
}
}
2)在import页面添加导出的链接
<a href="/export">导出</a>
3)测试。访问http://localhost:8080/import.html,点击导出,即可导出相应的数据。
SpringBoot文件上传与POI的使用的更多相关文章
- 补习系列(11)-springboot 文件上传原理
目录 一.文件上传原理 二.springboot 文件机制 临时文件 定制配置 三.示例代码 A. 单文件上传 B. 多文件上传 C. 文件上传异常 D. Bean 配置 四.文件下载 小结 一.文件 ...
- 【SpringBoot】07.SpringBoot文件上传
SpringBoot文件上传 1.编写html文件在classpath下的static中 <!DOCTYPE html> <html> <head> <met ...
- SpringBoot 文件上传临时文件路径问题
年后放假回来,一向运行OK的项目突然图片上传不了了,后台报错日志如下: java.io.IOException: The temporary upload location [/tmp/tomcat. ...
- springboot文件上传下载简单使用
springboot的文件上传比较简单 一.使用默认的Resolver:StandardServletMultipartResolver controller package com.mydemo.w ...
- springboot 文件上传大小配置
转自:https://blog.csdn.net/shi0299/article/details/69525848 springboot上传文件大小的配置有两种,一种是设置在配置文件里只有两行代码,一 ...
- SpringBoot文件上传下载
项目中经常会有上传和下载的需求,这篇文章简述一下springboot项目中实现简单的上传和下载. 新建springboot项目,前台页面使用的thymeleaf模板,其余的没有特别的配置,pom代码如 ...
- Springboot 文件上传(带进度条)
1. 相关依赖 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http ...
- SpringBoot 文件上传、下载、设置大小
本文使用SpringBoot的版本为2.0.3.RELEASE 1.上传单个文件 ①html对应的提交表单 <form action="uploadFile" method= ...
- SpringBoot文件上传异常之提示The temporary upload location xxx is not valid
原文: 一灰灰Blog之Spring系列教程文件上传异常原理分析 SpringBoot搭建的应用,一直工作得好好的,突然发现上传文件失败,提示org.springframework.web.multi ...
随机推荐
- (25)Vim 1
1.安装Vim CentOS 系统中,使用如下命令即可安装 Vim: yum install vim 需要注意的是,此命令运行时,有时需要手动确认 [y/n] 遇到此情况,选择 "y&quo ...
- php之魔术方法 __set(),__get(),__isset(),__unset()
__set()与__get() 当一个类里面,属性被设置为私有属性时,这个属性是不能在外部被访问的.那么当我们又想在外部访问时该怎么办呢,我们可以用方法来实现.举例如下: 1 class Test 2 ...
- WPF 之 MultiBinding(多路 Binding)(四)
一.前言 有时候 UI 需要显示的信息由不止一个数据来源决定,这时候就需要使用 MultiBinding ,即多路 Binding. MultiBinding 与 Binding 一样均以 B ...
- CF 1288 E. Messenger Simulator
CF 1288 E. Messenger Simulator 题目传送门 官方题解 题意想必大家都明白了这里就不赘述了,这里只想重点记录一下几种实现方法 分析 设向前移动的序列为\(a\)序列 对于没 ...
- Codeforces Round #327 (Div. 1) C. Three States
C. Three States time limit per test 5 seconds memory limit per test 512 megabytes input standard inp ...
- 远程连接 出现身份验证错误,要求的函数不受支持(这可能是由于CredSSP加密Oracle修正)
修改本地组策略: 计算机配置>管理模板>系统>凭据分配>加密Oracle修正 选择启用并选择"易受攻击". 原文:https://blog.csdn.net ...
- redis如何实现高可用【主从复制、哨兵机制】
实现redis高可用机制的一些方法: 保证redis高可用机制需要redis主从复制.redis持久化机制.哨兵机制.keepalived等的支持. 主从复制的作用:数据备份.读写分离.分布式集群.实 ...
- WPF Dispatcher 频繁调度导致的性能问题
问题 WPF Dispatcher 提供了UI线程之外的线程异步操作(请求)UI变化.一次Invoke/BeginInvoke调用产生一个DispatcherOperation,将挂在调度队列中,按照 ...
- 二进制安装kubernetes(七) 部署知识点总结
1.k8s各个组件之间通信,在高版本中,基本都是使用TSL通信,所以申请证书,是必不可少的,而且建议使用二进制安装,或者在接手一套K8S集群的时候,第一件事情是检查证书有效期,证书过期或者TSL通信问 ...
- 使用SignTool对软件安装包进行数字签名(一)--制作证书
一.制作根证书 1.开始菜单-运行-输入cmd,弹出命令行窗体. 2.输入命令:cd /d F:\SignTool,将当前工作目录修改到SignTool路径下. 3.使用makecert命令制作证书, ...