前后分离 上传下载文件demo
此篇文章只是我在学习中总结的一点经验,简单的小demo,只贴一些相关代码,里边加了注释,如有技术问题,欢迎指正。
本demo小介绍:没有扩展jpa的那部分。没有扩展后台限制文件大小的部分。文件上传到oracle Blob字段中存放(可自行扩展其它存放方式),在从中下载。
一、上传
react部分:
//引入:
import React from 'react';
import { Upload, Icon, message } from 'antd';
import { config } from '../../../../../common/config';
import styles from './uploadFile.less';
const { Dragger } = Upload;
const { contextPath } = config;
class EngineUploadComponent extends React.Component {
//在此可用于上传前的校验,可根据具体业务具体扩展
beforeUpload = file => {
// const png = file.type === "image/png";
// if (!png ) {
// message.error("图片格式不正确");
// return png ;
// }
const fileSize= file.size / 1024 / 1024 < 10;
if (!fileSize) {
message.error(file.name + "文件大小超出限制(10MB),请修改后重新上传");
return fileSize;
}
};
//在此可进行上传过程中或上传状态变化时处理
handleChange = (info) =>{
if(info.file.status ==='uploading'){//正在上传
}else if(info.file.status ==='done'){//上传成功
let fjmc = info.file.response.fjmc;
message.success(fjmc+'上传成功!');
}else if(info.file.status ==='error'){//上传失败
//let fjmc = info.file.response.fjmc;
message.error('上传失败!');
}
};
render() {
const { uploadUrl } = this.props;//后台接口,在此是调用此组件时传递url
return (
<div className={styles.engine_upload}>
<Dragger
name='file'//必须与后台接收参数对应
multiple='true'
action={`${contextPath}${uploadUrl}`}//拼接后台接口地址
data={{ 'name': 'xiaoming', 'age': '18'}}//往后台传递其他参数
beforeUpload={this.beforeUpload}
onChange={this.handleChange}
>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<div>添加文件</div>
</Dragger>
</div>
);
}
}
export default EngineUploadComponent;
如果发现粘贴代码,样式错乱,莫方,只是样式而已,先把流程整起来
java部分:
@ApiOperation(value = "上传文件", notes = "上传文件")
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public ResponseEntity<DOMAIN> uploadFile(@RequestParam("file") MultipartFile file) {
String oriName = file.getOriginalFilename();//获取文件名.类型
byte[] bytes = null;
try {
bytes = file.getBytes();
} catch (IOException e) {
e.printStackTrace();
}
DOMAIN domain = new DOMAIN();
domain.setFile(bytes);//在此注意后台Blob与byte[]对应
DOMAIN resultDomain = domainService.extendedSave(domain);
return ResponseEntity.status(HttpStatus.CREATED).body(resultDomain );
}
java 代码较为片面,仅作参考,自行扩展
二、下载
因为每个人编写习惯或者项目架构不同,所以下载部分仅贴关键点的代码,注意不在同一个文件喔~~
react部分:
//引入:
import axios from 'axios';
// axios :
export const uploadFileReq = ({ payload }) => {
const { downloadUrl, systemid } = payload;//downloadUrl:后台获取文件的接口,systemid :文件主键
if (!downloadUrl) return;
let queryParams = { }
return axios({
method: 'post',
url: `${config.contextPath}${downloadUrl}/${systemid}`,
data: '',
params: queryParams,
responseType: 'blob'//返回类型指定为blob类型
})
}
*handleOperation({ payload }, { call, put }) {
return yield call(uploadFileReq, { payload: payload });
}
downLoadFile =(systemid,fjmc,downloadUrl)=>{
const { dispatch} = this.props;
dispatch({ type: `XXXXX/handleOperation`, payload: {downloadUrl,systemid} }).then(res => {
//可在此处打印res,看看有哪些返回数据
const content = res.data;//获取返回的数据
const blob = new Blob([content]);
const fileName =fjmc;
//以下可模拟跳转url等多种方式实现
if ('download' in document.createElement('a')) { // 非IE下载,仅在chrome 80 及以上测试过,有兴趣的可进行多浏览器多版本测试
const elink = document.createElement('a');
elink.download = fileName; //文件名.类型
elink.style.display = 'none';
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else { // IE10+下载
navigator.msSaveBlob(blob, fileName);
}
})
}
//此方法用在Table中的下载按钮,在此引起一系列的调用,以至到最后的下载
// record:Table每行封装的数据
function downLoad({ record }){
let downloadUrl = 'XXXXX/XX/XXX/loadFile'; //建议在config中配置,在此引用,其它配置信息均此建议,方便维护修改
downLoadFile(record.SYSTEMID,record.FJMC,downloadUrl); //(文件主键,文件名称,下载地址)
}
以上前端部分仅是小demo,可自行根据业务拓展,例如 图片 压缩之类的
java部分:
@ApiOperation(value = "获取文件", notes = "获取文件")
@RequestMapping(value = "loadFile/{systemid}", method = RequestMethod.POST)
public void loadFile(@PathVariable("systemid") String systemid ,HttpServletResponse response ){
DOMAIN domain= domainService.extendedGet(systemid);
OutputStream os = null;
try {
os = response.getOutputStream();
response.reset();
response.setContentType("application/octet-stream;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
String fileName = domain.getFjmc();
response.setHeader("Content-Disposition", "attachment;charset=UTF-8; filename=" + fileName);
os.write(domain.getFile()); //注意这里的file是byte[]
} catch (Exception e) {
e.printStackTrace();
}
}