前言说明:springboot + vue + FastDFS实现文件上传(支持预览)升级版
FASTDFS部分
FASTDFS安装过程:基于centos 7安装FastDFS文件服务器
SpringBoot部分
springboot源码实现
package com.core.doc.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.doc.entity.FileInfo;
import com.core.doc.mapper.FileInfoMapper;
import com.core.doc.response.Result;
import com.core.doc.until.FastUtils;
//import org.openimaj.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/upload")
@CrossOrigin
public class UploadController {
@Autowired
FileInfoMapper fileInfoMapper;
/**
* 文件上传
**/
@PostMapping("/import")
public String importData(MultipartFile file, HttpServletRequest req) throws IOException {
System.out.println("file = " + file);
String name = file.getOriginalFilename();
String realPath = req.getSession().getServletContext().getRealPath("/");
System.out.println("realPath = " + realPath);
String fileId = FastUtils.upload(file);
// String url = "http://xx.xx.x.xx/" + fileId;
String url = fileId;
System.out.println(url);
return url;
}
/**
* 文件下载
**/
@GetMapping("/downloadFile")
public void downloadFile(HttpServletResponse response,String filePath) throws UnsupportedEncodingException {
// String filePath = "group1/M00/00/00/wKg4CmP7OiaAUzIvAADA8Mf85m8974.pdf";
// String fileName = "xxx.pdf";
// File file = new File(filePath);
// if(file.exists()) {
if(filePath == null)return;
QueryWrapper<FileInfo> wrapper = new QueryWrapper<>();
wrapper.eq("filePath",filePath);
List<FileInfo> fileInfos = fileInfoMapper.selectList(wrapper);
String filename = "未知文档.pdf";
if(fileInfos != null && fileInfos.size() > 0 && fileInfos.get(0).getFilename() != null ){
filename = fileInfos.get(0).getFilename() ;
if(!fileInfos.get(0).getFilename().contains(".pdf")){
filename = fileInfos.get(0).getFilename() +".pdf";
}
}
response.setContentType("application/force-download;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(filename.getBytes("gb2312"), "ISO-8859-1"));
byte[] bytes = FastUtils.testDownload(filePath);
FileInputStream fis = null;
System.out.println(filePath);
OutputStream outputStream = null;
int len = 0;
try {
outputStream = response.getOutputStream();
System.out.println(bytes);
if(bytes == null){
return;
}
outputStream.write(bytes);
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* 文件删除
**/
@PostMapping("/del")
@ResponseBody
public Result delFile(@RequestParam String fileName) {
int i = FastUtils.delFile(fileName);
if(i != -1){
return Result.ok().data("msg", "删除成功");
} else {
return Result.error().data("msg", "失败");
}
}
@PostMapping("/downlaod")
@ResponseBody
public byte[] upload(HttpServletResponse response, @RequestParam String fileName) {
byte[] bytes = FastUtils.testDownload(fileName);
response.setContentType("application/octet-stream;charset=UTF-8");
// 设置返回的文件类型
OutputStream toClient = null; // 得到向客户端输出二进制数据的对象
try {
response.setCharacterEncoding("UTF-8");
//使用setHeader方法设置浏览器使用UTF-8进行解码
response.setHeader("Content-Type", "text/html;charset=UTF-8");
toClient = response.getOutputStream();
toClient.write(bytes); // 输出数据
toClient.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
return bytes;
}
}
private void genCode(HttpServletResponse response, byte[] data) throws IOException {
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment; filename=\"declare.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
// IOUtils.write(data, (DataOutput) response.getOutputStream());
}
}
FastUtils工具类
package com.core.doc.until;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.junit.Test;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 文件上传工具类
*/
public class FastUtils {
private static StorageClient1 client1;
static {
try {
ClientGlobal.initByProperties("fastdfs-client.properties");
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
client1 = new StorageClient1(trackerServer, null);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
public static int delFile(String filename) {
int count = 0;
try {
count = client1.delete_file1(filename);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}finally {
return count;
}
}
public static String upload(MultipartFile file) {
String oldName = file.getOriginalFilename();
try {
return client1.upload_file1(file.getBytes(), oldName.substring(oldName.lastIndexOf(".") + 1), null);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
return null;
}
public static byte[] download(String filepath, HttpServletResponse response) throws IOException {
byte[] bytes = null;
try {
//1.初始化fastdfs客户端配置文件
ClientGlobal.initByProperties("fastdfs-client.properties");// 加载properties配置文件
System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");//输出properties中配置的参数,检测properties文件是否生效
System.out.println("charset=" + ClientGlobal.g_charset);
// 2.获取trackerServer
TrackerClient tracker = new TrackerClient();// 创建tracker客户端对象
TrackerServer trackerServer = tracker.getConnection();//获得tracker连接对象
//3.获取storageClient(通过trackerServer 和 storageServer:null)
StorageServer storageServer = null;
StorageClient1 client = new StorageClient1(trackerServer, storageServer);//通过tracker服务器返回storage服务器对象(客户端)
String name = "wKg4CmP7btCAZpAmAADA8Mf85m8679.pdf";
//4.下载操作
//方式一 文件id下载
bytes = client.download_file1("group1/M00/00/00/wKg4CmP7btCAZpAmAADA8Mf85m8679.pdf");//记得要传文件id返回字节流
File file=new File("D:\\KM\\"+name);// 给定文件路径 和 名称
FileOutputStream fileOutputStream=new FileOutputStream(file);//窗机输出流
fileOutputStream.write(bytes);//写入数据
fileOutputStream.close();//关闭输出流
//方式二 组名+文件路径
byte[] bytes2 = client.download_file("group1","/M00/00/00/"+name);//记得修改
File file2=new File("D:\\KM\\1"+name);// 给定文件路径 和 名称
FileOutputStream fileOutputStream2=new FileOutputStream(file2);//窗机输出流
fileOutputStream2.write(bytes);//写入数据
fileOutputStream2.close();//关闭输出流
trackerServer.close();
} catch (Exception ex) {
ex.printStackTrace();
}finally {
return bytes;
}
}
public static byte[] testDownload(String filename) {
byte[] bytes = null;
try {
//1.初始化fastdfs客户端配置文件
ClientGlobal.initByProperties("fastdfs-client.properties");// 加载properties配置文件
System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");//输出properties中配置的参数,检测properties文件是否生效
System.out.println("charset=" + ClientGlobal.g_charset);
// 2.获取trackerServer
TrackerClient tracker = new TrackerClient();// 创建tracker客户端对象
TrackerServer trackerServer = tracker.getConnection();//获得tracker连接对象
//3.获取storageClient(通过trackerServer 和 storageServer:null)
StorageServer storageServer = null;
StorageClient1 client = new StorageClient1(trackerServer, storageServer);//通过tracker服务器返回storage服务器对象(客户端)
String name = "wKg4CmP7btCAZpAmAADA8Mf85m8679.pdf";
//4.下载操作
//方式一 文件id下载
bytes = client.download_file1(filename);//记得要传文件id返回字节流
// File file=new File("D:\\KM\\"+name);// 给定文件路径 和 名称
// FileOutputStream fileOutputStream=new FileOutputStream(file);//窗机输出流
// fileOutputStream.write(bytes);//写入数据
// fileOutputStream.close();//关闭输出流
//方式二 组名+文件路径
// byte[] bytes2 = client.download_file("group1","/M00/00/00/"+name);//记得修改
// File file2=new File("D:\\KM\\1"+name);// 给定文件路径 和 名称
// FileOutputStream fileOutputStream2=new FileOutputStream(file2);//窗机输出流
// fileOutputStream2.write(bytes);//写入数据
// fileOutputStream2.close();//关闭输出流
trackerServer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
finally {
return bytes;
}
}
}
Vue部分
vue预览功能参考:vue-pdf实现pdf文件在线预览
vue预览功能结合实现(以下代码为案例代码:核心代码)
一、本地测试环境,需要配置跨域
在vue.config.js中配置需要跨域的IP地址
'pdf': {
target: 'http://xxx.xxx.xx.x/',
changOrigin: true,
pathRewrite: {
'^/pdf': ''
}
}
其中 pdfUrl 只需赋值 后缀即可如下所示
group1/M00/00/01/wKg4CmQVuuiAZRYnAALX0oge5B8291.pdf
<el-dialog title="查看" :visible.sync="showVisible" :width="hxi+'%'">
<div class="pdf" :visible.sync="showVisible">
<div class="pdf-tab">
<!-- <div class="btn-def"
@click.stop="clock">顺时针</div>
<div class="btn-def"
@click.stop="counterClock">逆时针</div> -->
</div>
<el-button type="success" :class="{select:idx==0}"
@touchstart="idx=0"
@touchend="idx=-1"
@click="scaleD">
放大
</el-button>
<el-button type="success" :class="{select:idx==1}"
@touchstart="idx=1"
@touchend="idx=-1"
@click="scaleX">
缩小
</el-button>
<!-- <div>进度:{{loadedRatio}}</div> -->
<!-- <div>页面加载成功: {{curPageNum}}</div> -->
<div class="main">
<pdf ref="pdf"
:src="pdfUrl"
:page="pageNum"
:rotate="pageRotate"
@password="password"
@progress="loadedRatio = $event"
@page-loaded="pageLoaded($event)"
@num-pages="pageTotalNum=$event"
@error="pdfError($event)"
@link-clicked="page = $event">
</pdf>
<div style="float:right">{{pageNum}}/{{pageTotalNum}}</div>
</div>
<div>
<el-button class="btn-def btn-pre" type="success"
@click.stop="prePage" style="mar">上一页</el-button>
<el-button class="btn-def btn-next" type="primary"`在这里插入代码片`
@click.stop="nextPage">下一页 </el-button>
</div>
</div>
</el-dialog>
二、若是部署上线,无法预览需要配置nginx进行地址映射,比如部署的tomcat服务器地址为 8080端口,而安装的DFS服务器为80端口,那就将tomcat的8080端口,配置代理为
location /pdf/{
proxy_pass http://xxx.xxx.xx.xx:8080/;
}
下载功能,目前实现就是结合后端,通过io流的形式,进行跳转下载
,vue处理代码如下:
window.location.href = 'http://xxx.xxx.xx.xx:8082/upload/downloadFile?filePath='+this.FileData.filepath;
文件上传功能,结合 element ui
只需将action 改为自己的接口即可,springboot的源码在上面
<el-upload
class="upload-demo"
action="https://localhost:8082/upload/file"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>