springboot文件上传与下载
功能实现:
上传:将本地文件如(excel、png)等上传至指定目录,并将路径储存到数据库;
下载:根据文件id下载指定文件
1.sql
-- 创建files表用来储存文件信息
DROP TABLE IF EXISTS `files`;
CREATE TABLE `files` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`file_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`file_suffix` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
2.pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--tk.mybatis-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.4</version>
</dependency>
<!--Pojo-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<!-- stringutils工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
3.yml
server:
port: 8080
servlet:
context-path: /
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
username: root
password: 890504@qQ#
driver-class-name: com.mysql.cj.jdbc.Driver
#Spring Boot2.0之后的版本配置 文件上传:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
logging:
level:
com:
test:
optfile:
dao: off
mybatis:
configuration:
map-underscore-to-camel-case: true
file:
save-path: D:/temp/files
4.entity
package com.test.optfile.entity;
import lombok.*;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Files implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
/**
* 文件存储路径
*/
private String filePath;
/**
* 文件名称
*/
private String fileName;
/**
* 文件后缀名
*/
private String fileSuffix;
}
5.dao
package com.test.optfile.dao;
import com.test.optfile.entity.Files;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
@Repository
public interface FileMapper extends Mapper<Files> {
@Select("select * from files where id = #{id}")
Files selectById(@Param("id") int id);
}
6.service
package com.test.optfile.service;
import com.test.optfile.entity.Files;
import com.test.optfile.utils.Result;
import org.springframework.web.multipart.MultipartFile;
public interface FileService {
Result upLoadFiles(MultipartFile file);
Files getFileById(int id);
}
7.serviceImpl
package com.test.optfile.service.impl;
import com.test.optfile.dao.FileMapper;
import com.test.optfile.entity.Files;
import com.test.optfile.service.FileService;
import com.test.optfile.utils.ResponseCode;
import com.test.optfile.utils.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
@Service
public class FileServiceImpl implements FileService {
@Value("${file.save-path}")
private String savePath;
@Autowired
private FileMapper fileMapper;
@Override
public Result upLoadFiles(MultipartFile file) {
//设置支持最大上传的文件,这里是1024*1024*20=20M
long MAX_SIZE = 20971520L;
//获取要上传文件的名称
String fileName = file.getOriginalFilename();
//如果名称为空,返回一个文件名为空的错误
if (StringUtils.isEmpty(fileName)) {
return new Result(ResponseCode.FILE_NAME_EMPTY.getCode(), ResponseCode.FILE_NAME_EMPTY.getMsg(), null);
}
//如果文件超过最大值,返回超出可上传最大值的错误
if (file.getSize() > MAX_SIZE) {
return new Result(ResponseCode.FILE_MAX_SIZE.getCode(), ResponseCode.FILE_MAX_SIZE.getMsg(), null);
}
//获取到后缀名
String suffixName = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf(".")) : null;
//文件的保存重新按照时间戳命名
String newName = System.currentTimeMillis() + suffixName;
File newFile = new File(savePath, newName);
if (!newFile.getParentFile().exists()) {
newFile.getParentFile().mkdirs();
}
try {
//文件写入
file.transferTo(newFile);
} catch (IOException e) {
e.printStackTrace();
}
//将这些文件的信息写入到数据库中
Files files = new Files();
files.setFilePath(newFile.getPath());
files.setFileName(fileName);
files.setFileSuffix(suffixName);
fileMapper.insert(files);
return new Result(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), "数据上传成功");
}
//根据id获取文件信息
@Override
public Files getFileById(int id) {
Files files = fileMapper.selectById(id);
return files;
}
}
8.controller
package com.test.optfile.controller;
import com.test.optfile.entity.Files;
import com.test.optfile.service.FileService;
import com.test.optfile.utils.ResponseCode;
import com.test.optfile.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
@RestController
@RequestMapping("/api")
@CrossOrigin
public class FileController {
@Autowired
private FileService fileService;
//localhost:8080/api/upload,这里建议使用postmen上传文件,格式form-data
//文件上传接口
@Transactional
@PostMapping("/upload")
public Result upLoadFiles(MultipartFile multipartFile) {
//如果文件为空,直接返回错误信息
if (multipartFile.isEmpty()) {
return new Result(ResponseCode.FILE_EMPTY.getCode(), ResponseCode.FILE_EMPTY.getMsg(), null);
}
//否则调用service上传文件
return fileService.upLoadFiles(multipartFile);
}
//localhost:8080/api/download?id=1,这里建议使用浏览器下载
//文件下载接口
@Transactional
@GetMapping("/download")
public void downloadFiles(int id,
HttpServletResponse response){
Files files = fileService.getFileById(id);
if(files == null){
throw new RuntimeException("files is not exits!");
}
InputStream inputStream = null;
ServletOutputStream outputStream = null;
try {
// 读到流中
inputStream = new FileInputStream(files.getFilePath());// 文件的存放路径
response.reset();
response.setContentType("application/octet-stream");
String filename = new File(files.getFilePath()).getName();
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
outputStream = response.getOutputStream();
byte[] b = new byte[1024];
int len;
//从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
}catch (IOException e){
e.printStackTrace();
} finally {
try {
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
9.springboot启动类
package com.test.optfile;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@MapperScan({"com.test.optfile.dao"})
@SpringBootApplication
public class OptFileApplication {
public static void main(String[] args) {
SpringApplication.run(OptFileApplication.class, args);
}
}