要想实现文件上传和下载,其实只需要下述代码即可:
文件上传和下载
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.Result;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
/**
* 文件上传下载接口
*/
@RestController
@RequestMapping("/files")
public class FileController {
// 文件上传存储路径
private static final String filePath = System.getProperty("user.dir") + "/file/";
/**
* 文件上传
*
* @param file 待上传的文件
* @return 返回上传文件的标识符
*/
@PostMapping("/upload")
public Result upload(MultipartFile file) {
synchronized (FileController.class) {
// 生成唯一标识符,避免文件覆盖
String flag = System.currentTimeMillis() + ""; //当前时间戳
String fileName = file.getOriginalFilename(); //文件原始名称
try {
// 确保文件存储目录存在
if (!FileUtil.isDirectory(filePath)) {
FileUtil.mkdir(filePath);
}
// 文件存储形式:时间戳-文件名
FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName);
System.out.println(fileName + "--上传成功");
Thread.sleep(1L);
} catch (Exception e) {
System.err.println(fileName + "--文件上传失败");
}
// 返回文件标识符
return Result.success(flag);//返回的是时间戳【数据库中存储的也是那个时间戳】相当于唯一的ID
}
}
/**
* 获取文件
*
* @param flag 文件的标识符
* @param response 用于返回文件流
*/
@GetMapping("/{flag}") //根据时间戳
public void avatarPath(@PathVariable String flag, HttpServletResponse response) {
// 确保文件存储目录存在
if (!FileUtil.isDirectory(filePath)) {
FileUtil.mkdir(filePath);
}
OutputStream os;
List<String> fileNames = FileUtil.listFileNames(filePath);
// 根据标识符查找对应的文件名
String avatar = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");
try {
if (StrUtil.isNotEmpty(avatar)) {
// 设置返回的文件名
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(avatar, "UTF-8"));
response.setContentType("application/octet-stream");
// 读取文件内容并返回
byte[] bytes = FileUtil.readBytes(filePath + avatar);
os = response.getOutputStream();
os.write(bytes);
os.flush();
os.close();
}
} catch (Exception e) {
System.out.println("文件下载失败");
}
}
}
上述代码,算是固定写法!!可以用来上传图片,文件等资源!
拿走不谢!!
只用来看文件上传下载其实没啥意思!小编是在图书信息管理的基础上来进行图片封面的上传的!
相关代码:
图书信息管理的增删改查
- 创建数据库表
CREATE TABLE `book` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书名称',
`price` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书价格',
`author` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书作者',
`press` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书出版社',
`img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图书封面',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- 创建实体类Book.java
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "price")
private String price;
@Column(name = "author")
private String author;
@Column(name = "press")
private String press;
@Column(name = "img")
private String img;
}
- BookDao.java BookMapper.xml
import com.example.entity.Book;
import com.example.entity.Params;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
@Repository
public interface BookDao extends Mapper<Book> {
List<Book> findBySearch(@Param("params") Params params);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.dao.BookDao">
<select id="findBySearch" resultType="com.example.entity.Book">
select * from book
<where>
<if test="params != null and params.name != null and params.name != ''">
and name like concat('%', #{ params.name }, '%')
</if>
<if test="params != null and params.author != null and params.author != ''">
and author like concat('%', #{ params.author }, '%')
</if>
</where>
</select>
</mapper>
- BookService.java
import com.example.dao.BookDao;
import com.example.entity.Book;
import com.example.entity.Params;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class BookService {
@Resource
private BookDao bookDao;
public PageInfo<Book> findBySearch(Params params) {
// 开启分页查询
PageHelper.startPage(params.getPageNum(), params.getPageSize());
// 接下来的查询会自动按照当前开启的分页设置来查询
List<Book> list = bookDao.findBySearch(params);
return PageInfo.of(list);
}
public void add(Book book) {
bookDao.insertSelective(book);
}
public void update(Book book) {
bookDao.updateByPrimaryKeySelective(book);
}
public void delete(Integer id) {
bookDao.deleteByPrimaryKey(id);
}
}
- BookController.java
import com.example.common.Result;
import com.example.entity.Book;
import com.example.entity.Params;
import com.example.service.BookService;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@CrossOrigin
@RestController
@RequestMapping("/book")
public class BookController {
@Resource
private BookService bookService;
@GetMapping("/search")
public Result findBySearch(Params params) {
PageInfo<Book> info = bookService.findBySearch(params);
return Result.success(info);
}
@PostMapping
public Result save(@RequestBody Book book) {
if (book.getId() == null) {
bookService.add(book);
} else {
bookService.update(book);
}
return Result.success();
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
bookService.delete(id);
return Result.success();
}
}
图书封面文件上传
- FileController.java
- 上传下载接口不能拦截,需要放行
jwt令牌拦截器那块内容
// 加自定义拦截器JwtInterceptor,设置拦截规则
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**")
.excludePathPatterns("/api/files/**")
.excludePathPatterns("/api/admin/login")
.excludePathPatterns("/api/admin/register");
}
- BookView.vue
el-upload:Element - The world's most popular Vue UI framework
<el-form-item label="图书封面" label-width="20%">
<el-upload action="http://localhost:8080/api/files/upload" :on-success="successUpload">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
successUpload(res) {
this.form.img = res.data;
},
图书封面预览、下载
el-image:Element - The world's most popular Vue UI framework
<el-table-column label="图书封面">
<template v-slot="scope">
<el-image
style="width: 70px; height: 70px; border-radius: 50%"
:src="'http://localhost:8080/api/files/' + scope.row.img"
:preview-src-list="['http://localhost:8080/api/files/' + scope.row.img]">
</el-image>
</template>
</el-table-column>
<el-button type="primary" @click="down(scope.row.img)">下载</el-button>
down(flag) {
location.href = 'http://localhost:8080/api/files/' + flag
}
恭喜你,看到了最后,浪费了你一俩分钟时间,其实下面的图书信息管理的增删改查都是废话内容,最重要的就是上面的文件上传和下载,但是你还是看下去了!感谢你的信赖!