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的使用的更多相关文章

  1. 补习系列(11)-springboot 文件上传原理

    目录 一.文件上传原理 二.springboot 文件机制 临时文件 定制配置 三.示例代码 A. 单文件上传 B. 多文件上传 C. 文件上传异常 D. Bean 配置 四.文件下载 小结 一.文件 ...

  2. 【SpringBoot】07.SpringBoot文件上传

    SpringBoot文件上传 1.编写html文件在classpath下的static中 <!DOCTYPE html> <html> <head> <met ...

  3. SpringBoot 文件上传临时文件路径问题

    年后放假回来,一向运行OK的项目突然图片上传不了了,后台报错日志如下: java.io.IOException: The temporary upload location [/tmp/tomcat. ...

  4. springboot文件上传下载简单使用

    springboot的文件上传比较简单 一.使用默认的Resolver:StandardServletMultipartResolver controller package com.mydemo.w ...

  5. springboot 文件上传大小配置

    转自:https://blog.csdn.net/shi0299/article/details/69525848 springboot上传文件大小的配置有两种,一种是设置在配置文件里只有两行代码,一 ...

  6. SpringBoot文件上传下载

    项目中经常会有上传和下载的需求,这篇文章简述一下springboot项目中实现简单的上传和下载. 新建springboot项目,前台页面使用的thymeleaf模板,其余的没有特别的配置,pom代码如 ...

  7. Springboot 文件上传(带进度条)

    1. 相关依赖 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http ...

  8. SpringBoot 文件上传、下载、设置大小

    本文使用SpringBoot的版本为2.0.3.RELEASE 1.上传单个文件 ①html对应的提交表单 <form action="uploadFile" method= ...

  9. SpringBoot文件上传异常之提示The temporary upload location xxx is not valid

    原文: 一灰灰Blog之Spring系列教程文件上传异常原理分析 SpringBoot搭建的应用,一直工作得好好的,突然发现上传文件失败,提示org.springframework.web.multi ...

随机推荐

  1. 一文弄懂-BIO,NIO,AIO

    目录 一文弄懂-BIO,NIO,AIO 1. BIO: 同步阻塞IO模型 2. NIO: 同步非阻塞IO模型(多路复用) 3.Epoll函数详解 4.Redis线程模型 5. AIO: 异步非阻塞IO ...

  2. .NET 微服务

    前文传送门: 什么是云原生? 现代云原生设计理念 Microservices 微服务是构建现代应用程序的一种流行的体系结构样式,云原生系统拥抱微服务. 微服务是由一组(使用共享结构交互的.独立的小块服 ...

  3. Triangle War POJ - 1085 极小极大搜索

    参考链接:https://www.cnblogs.com/nwpuacmteams/articles/5697873.html 极小极大搜索 的个人理解(alpha-beta剪枝):https://w ...

  4. C++ string (浅谈)

    浅谈string <string> typedef basic_string<char> string; 本篇主要内容是简单地介绍 string类 在竞赛方面较实用的一些功能, ...

  5. Kafka官方文档V2.7

    1.开始 1.1 简介 什么是事件流? 事件流相当于人体的中枢神经系统的数字化.它是 "永远在线 "世界的技术基础,在这个世界里,业务越来越多地被软件定义和自动化,软件的用户更是软 ...

  6. codeforces 11B Jumping Jack

    Jack is working on his jumping skills recently. Currently he's located at point zero of the number l ...

  7. 北京网络赛G BOXES 大模拟+BFS

    题目描述 Description There is a strange storehouse in PKU. In this storehouse there are n slots for boxe ...

  8. Gym 100796B Wet Boxes(思维)题解

    题意:给一个如图坐标系,每个方形都放在下面两个中间,已知一个木块湿了那么他下面所有的都会湿,显然,不能湿两次.问,每次给出一个坐标,把他弄湿,有几个木块从干变成湿了. 思路:我们把坐标系拉直,就变成了 ...

  9. windows信息收集

      导语:介绍 特权升级总是被归结为适当的枚举.但要完成适当的枚举,你需要知道要检查和查找的内容.这通常需要伴随着经验的丰富而对系统非常熟悉.起初特权升级看起来像是一项艰巨的任务,但过了一段时间,你就 ...

  10. Docker & Node.js

    Docker & Node.js https://nodejs.org/en/docs/guides/nodejs-docker-webapp/ https://docs.docker.com ...