环境
angular/cli:1.7.4
node:v8.11.2
ng-zorro:0.7
后端使用spring-boot做一个上传文件的接口,前端工程上传文件的时候对接后端的接口就可以了。下面说一下怎么使用。
启动一下,没什么问题开始编写后端上传文件的代码
这里就不搞什么三层架构了,就一个上传文件,直接在web包下新建一个类FileUploadController
package com.lautumn.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@RestController
public class FileUploadController {
@RequestMapping("/upload")
public Map<String, String> upload(@RequestParam("upload_file")MultipartFile file) {
String path = "/Users/lautumn/JAVALEARN/web/upload"; // 文件保存路径
/**
* 可能会出现重复文件,所以我们要对文件进行一个重命名的操作
* 截取文件的原始名称,然后将扩展名和文件名分开,使用:时间戳-文件名.扩展名的格式保存
*/
// 获取文件名称
String fileName = file.getOriginalFilename();
// 获取扩展名
String fileExtensionName = fileName.substring(fileName.lastIndexOf(".") + 1);
// 获取文件名
String name = fileName.substring(0, fileName.lastIndexOf("."));
// 生成最终保存的文件名,格式为: 时间戳-文件名.扩展名
String id = String.valueOf(new Date().getTime());
String saveFileName = id + "-" + name + "." + fileExtensionName;
/**
* 上传操作:可能upload目录不存在,所以先判断一下如果不存在,那么新建这个目录
*/
File fileDir = new File(path);
if (!fileDir.exists()){
fileDir.setWritable(true);
fileDir.mkdirs();
}
/**
* 上传
*/
File targetFile = new File(path, saveFileName);
try {
file.transferTo(targetFile);
} catch (IOException e) {
e.printStackTrace();
}
/**
* 返回值,这三个对象是ng-zorro那边需要的
*/
Map<String, String> result = new HashMap<>();
result.put("url", String.format("http://localhost:8080/upload/%s", saveFileName));
result.put("uid", id);
result.put("name", fileName);
return result;
}
}
说明:注释都有,如果不知道上传路径怎么写就在项目目录下右键copy一下路径填上就好了。
然后在resource/static 下新建一个index.html 测试一下上传是否成功。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file">
<button type="submit">上传</button>
</form>
</body>
</html>
启动项目访问localhost:8080/index.html
这时候点击链接是访问不到的,因为还没有配置静态资源访问路径。
这时候重启项目再次上传文件的操作,点击返回的url应该可以了。
这里还有一个问题,因为我们是前后端分离的,待会前端项目启动端口肯定不能和后端的一样,所以会有跨域的问题,
那么接下来是前端的事情,这里就不详细说搭建项目过程了,这里采用的NG-ZORRO的版本是0.7x,给个官网链接,按照官网示例搭建项目https://ng.ant.design/version/0.7.x/docs/getting-started/zh。
拷贝一段ng-zorro的uoload示例
- app.component.ts
import { Component } from '@angular/core';
import {NzMessageService, UploadFile} from 'ng-zorro-antd';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
fileList = [
{
uid: -1,
name: 'xxx.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
}
];
previewImage = '';
previewVisible = false;
constructor(private msg: NzMessageService) {}
handlePreview = (file: UploadFile) => {
this.previewImage = file.url || file.thumbUrl;
this.previewVisible = true;
}
}
- app.component.html
<nz-upload
nzAction="https://jsonplaceholder.typicode.com/posts/"
nzListType="picture-card"
[(nzFileList)]="fileList"
[nzShowButton]="fileList.length < 3"
[nzPreview]="handlePreview">
<i class="anticon anticon-plus"></i>
<div class="ant-upload-text">Upload</div>
</nz-upload>
<nz-modal [nzVisible]="previewVisible" [nzContent]="modalContent" [nzFooter]="null" (nzOnCancel)="previewVisible=false">
<ng-template #modalContent>
<img [src]="previewImage" [ngStyle]="{ 'width': '100%' }" />
</ng-template>
</nz-modal>
启动angular工程,页面展示
这时候对接我们写的后端上传文件了。
首先在app.component.html里将nzAction修改为我们写的后端地址
这时候问题来了,我们后端的上传逻辑需要传一个名字为upload_file的参数,这个要怎么办呢?
查看官网得知,可以使用nzName来指定上传文件的参数
这时候两个项目启动起来,测试上传
这里有一个问题,有时候点击上传的时候会出现文件上传中,但是缩略图没出来
查看后台发现文件已经到后台了,这时候可以点击一下其他图片的预览,或者点击一下上传的按钮再关闭试试
具体原因我也不太清楚,但是在后端工程中上传的时候睡眠1秒左右,或者在Chrome浏览器的网速调整至3g就可以保证每次都会出预览图,我觉得可能是本地开发中上传文件速度太快还是怎么样,没能检测到吧。如果有哪位知道真实原因麻烦告知一下,以及解决办法,毕竟上传文件的时候睡眠一秒,不是很合理,如果是在真实线上环境应该没问题吧,可能原因还是上传的速度太快没检测到,如果在真实线上环境,有网络的延迟应该是可以每次都出预览图的。具体我没有试验过。仅猜测。有解决方法的还请告知我一声,感激。
以上就完成了。