文章目录
注
需求描述:
需求其实很简单就是文件下载。
前端以下简称为:client
后端服务器简称:oneServer
文件所在服务器简称:fileServer
解决方案
- 运用jcifs包中的SmbFile方法,oneServer只需要知道fileServer的用户名密码,就可以直接访问到fileServer中的文件。
SmbFile file = new SmbFile(“smb://guest:123@10.1.88.3/uplo/test.txt”);
此方法详细实现可以百度哈。
没采用该方案的原因:
- 因为我们公司的服务器密码是时常更新的,每次都到服务器密码系统申请才能登录。
- 这种方法会存在一定的安全问题。
- 将fileServer做成FTP服务器,这样oneServer访问fileServer就也很方便。
没采用该方案的原因:
- 公司已经有文件服务器了,只是我们项目特殊,没有接入而已
- 由于我之前没有做过FTP服务器,怕耗时过长,影响项目进度。
- 即使做出了FTP服务器,后续架构评审也会非常耗时。
- 写一个JavaWeb项目到fileServer,让其提供文件下载接口,oneServer通过请求该接口下载文件并发送给client。
采用该方案的原因
- 无需公司架构评审。只需要写一个javaWeb程序提供服务即可。
- 只需要操作流,fileServer读取文件信息流传送给oneServer,oneServer直接把流传输给前端,只需要考虑信息流的高效即可。
以上这三种方案都是可以实现的,肯定不只局限于这三种方案。才疏学浅,只能想到这三种,有好的方法还请告知。
实现过程
1.前端需要用axios发送请求,因为后台需要做校验,如果直接用window.location.href
,无法向后端传递用户信息(sessionId),因为我们的前端用的vue,前后端连接会跨域,所以axios请求里面需要自己设置sessionId。
前端代码如下:
downloadfile(){
if(this.systemFolderName == null){
this.$Message.error({
content:"请选择系统",
duration:2
});
return;
}
if(this.fileName == null){
this.$Message.error({
content:"请选择文件",
duration:2
});
return;
}
var postData = this.$qs.stringify({
path: this.systemFolderName + "/" + this.fileName
});
this.$axios({
method: 'post',
url: 'downloadfile/remotefile',
data: postData,
responseType: 'arraybuffer'
}).then(response => {
if (response.headers['content-type'].indexOf('json') === -1) {// 返回的数据不是
this.download(response.data);
}else{
if (response.request.responseType === 'arraybuffer' && response.data.toString() === '[object ArrayBuffer]') {
// 返回的数据是 arraybuffer,内容是 json
var text = Buffer.from(response.data).toString('utf8');
var json = JSON.parse(text);
if("N" == json.code){
this.$Message.error({
content:json.message,
duration:2
});
}
}
}
}).catch((error) => {
})
},
download (data) {
if (!data) {
return;
}
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', this.fileName)
document.body.appendChild(link)
link.click()
}
此方法借鉴和参考以下两位博主的博客:
1、http://www.cnblogs.com/yulj/p/8494465.html
2、http://blog.tubumu.com/2017/12/27/axios-extension-01/
**注意:**如果只用博客一的方法,后端下载如果报错,那么前端依旧会显示成功,需要再前后端做沟通,统一报错信息,以便前端判断。
{"code":"N","body":null,"message":"Required String parameter 'path' is not present","status":null}
这是我们项目统一的返回格式,所以需要如代码中所写,在下载失败时做提示。
2.oneServer接收client传输的参数,向fileServer发送请求,并接收fileServer返回的信息流,然后返回给client,其实就是充当中转站。
oneServer实现代码如下:
public void remoteFile(@NotNull(message = "路径不能为空") @RequestParam("path") String path, HttpServletResponse response,
HttpServletRequest request) throws IOException, ServletException {
String url = REMOTE_URL + "?selectPath=" + path;
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse res = httpclient.execute(httpGet);
byte[] datas=null;
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = res.getEntity();
datas = EntityUtils.toByteArray(entity);
}
response.setContentType("multipart/form-data");
response.setCharacterEncoding("UTF-8");
try ( ByteArrayInputStream in = new ByteArrayInputStream(datas);
OutputStream out = response.getOutputStream()) {
int b = 0;
byte[] buffer = new byte[1024];
while (b != -1) {
b = in.read(buffer);
out.write(buffer, 0, b);
}
out.flush();
} catch (IOException e) {
logger.error("前端取消下载", e);
}
}
此处应该可以改进,我本身对IO并不熟悉,这些方法这是可以实现需求,我还没有深入了解,如果错误还请留言之处,谢谢。
3.fileServer接收oneServer的请求后,去读取文件,并将文件返回给oneServer。
fileServer实现代码如下:
public void downloadFile(String selectPath, HttpServletResponse response) throws IOException {
response.setContentType("multipart/form-data");
response.setCharacterEncoding("UTF-8");
File file = new File(LogsFileConfigure.LOGS_ROOT_PATH + selectPath);
try (
OutputStream out = response.getOutputStream();
FileInputStream inputStream = new FileInputStream(file)) {
int b = 0;
byte[] buffer = new byte[1024];
while (b != -1) {//不能一次性读完,大文件会内存溢出(不能直接fis.read(buffer);
b = inputStream.read(buffer);
out.write(buffer, 0, b);
}
out.flush();
} catch (IOException e) {
logger.error("读取文件失败", e);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/69864.html