基于目前商城项目的开发,需要将图片上传至Nginx+VSFTP搭建的图片服务器,如果你只想了解如何使用java实现将图片等文件上传至VSFTP服务器,可以直接参考相关上传代码即可,要不然看起来会有点复杂,因为涉及到多服务器、存在跨域问题,以下是关于本案例的一些说明:
1、前端是基于Vue+ElementUI,后端是基于SpringBoot
2、前后端分离,前端项目放在81端口的Nginx服务器上,后端项目部署在8080端口的tomcat服务器上
3、Nginx+VSFTP搭建的图片服务器是在ip为192.168.223.128的Linux虚拟机上,关于其搭建可参考:
一、前期准备 1、环境准备:我这里使用的是CentOS7 64位Linux操作系统 2、安装与配置Nginx服 […]
参考ElementUI官网上传图片的组件,我这里选择手工上传的组件,在前端项目中新建了Upload.vue,代码如下:
<template>
<div>
<el-upload
class="upload-demo"
ref="upload"
action="http://localhost:81/admin/file/upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</div>
</template>
<script>
export default {
data(){
return {
fileList: []
};
},
methods:{
submitUpload() {
this.$refs.upload.submit();
}
}
}
</script>
<style scoped>
</style>
注意这里的action请求是发送到http://localhost:81/admin/file/upload,前端项目的部署在81端口的Nginx服务器,如果直接发送给8080的tomcat服务器,会存在跨域问题,关于跨域问题请参考:
文章目录 总结 在进行前端网页开发尤其是在调用接口时经常会遇到跨域问题,导致接口调用失败(浏览器端类似报错如下 […]
因此,我在81端口的Nginx服务器上配置了反向代理,具体部分配置如下(匹配/admin/转发到8080):
listen 81;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /admin/ {
proxy_pass http://127.0.0.1:8080;
}
1、在pom.xml中引入commons-net用于FTP上传的jar包,这里我使用的是3.7.2版本,具体坐标如下:
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.7.2</version>
</dependency>
2、在application.yml配置文件中新增ftp相关配置,如下:
#ftp配置 ftp: #ftp所在主机ip或主机名 host: 192.168.223.128 #ftp端口号 port: 21 #ftp请求的用户名 username: panziye #ftp请求的密码 password: 123456 #ftp根路径 我这里设为/www basePath: /www
3、在util包下新建FtpUtil.java,具体代码如下:
package com.panziye.shop.util;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;
@Component
@ConfigurationProperties(prefix = "ftp")
public class FtpUtil {
private String host;
private Integer port;
private String username;
private String password;
private String basePath;
/**
* 上传文件
* @param filePath 文件上传目录
* @param fileName 文件上传后名称
* @param inputStream 文件流
* @return
*/
public Boolean uploadFile(String filePath,String fileName, InputStream inputStream) {
//1、目标上传路径
String targetPath = basePath+filePath;
//2、创建FTPClient对象
FTPClient ftp = new FTPClient();
try {
//3、定义返回的状态码
int reply;
//4、连接ftp
ftp.connect(host,port);
//5、输入账号和密码进行登录
ftp.login(username, password);
//6、接受状态码(如果成功,返回230,如果失败返回503)
reply = ftp.getReplyCode();
//7、根据状态码检测ftp的连接,如果连接成功返回true,否则返回false
if (!FTPReply.isPositiveCompletion(reply)) {
//说明连接失败,需要断开连接
ftp.disconnect();
return false;
}
// 8、切换工作目录,成功返回true,否则返回false
if(!ftp.changeWorkingDirectory(targetPath)){
//切换不成功表示目录不存在,则创建该目录并切换进去
boolean f = createDirecroty(targetPath,ftp);
ftp.changeWorkingDirectory(targetPath);
}
//9、设置被动模式(根据自己ftp的设置来决定,默认是主动模式)
//模式错误可能会导致上传超时,文件大小为0的情况
ftp.enterLocalPassiveMode();
//10、把文件转换为二进制字符流的形式进行上传
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//11、上传文件到该目录
ftp.storeFile(fileName,inputStream);
//12、关闭输入流
inputStream.close();
// 13.退出ftp
ftp.logout();
}catch (Exception e){
e.printStackTrace();
}finally {
if (ftp.isConnected()) {
try {
// 14.断开ftp的连接
ftp.disconnect();
} catch (Exception ioe) {
ioe.printStackTrace();
}
}
}
return true;
}
//创建多层目录文件
public Boolean createDirecroty(String remote, FTPClient ftp) throws IOException {
boolean flag = true;
StringTokenizer s = new StringTokenizer(remote, "/");
s.countTokens();
String pathName = "";
while (s.hasMoreElements()) {
pathName = pathName + "/" + (String) s.nextElement();
try {
ftp.makeDirectory(pathName);
} catch (Exception e) {
e.printStackTrace();
flag = false;
}
}
return flag;
}
public void setHost(String host) {
this.host = host;
}
public void setPort(Integer port) {
this.port = port;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
}
4、新建FileController.java测试类,代码如下:
package com.panziye.shop.controller;
import com.panziye.shop.http.ResponseResult;
import com.panziye.shop.util.FtpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
@RestController
@RequestMapping("/admin/file")
public class FileController {
@Autowired
private FtpUtil ftpUtil;
@PostMapping("/upload")
public ResponseResult upload(MultipartFile file){
//图片保存路径:后期可以定义到常量类中,时间目录可以动态生成,以便复用和修改
String filePath = "/images/2020";
//图片原名称
String originalName = file.getOriginalFilename();
//生成随机名称
String fileName = UUID.randomUUID()+originalName.substring(originalName.lastIndexOf("."));
try {
//上传
ftpUtil.uploadFile(filePath,fileName,file.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
//可以返回图片相对路径
return ResponseResult.ok();
}
}
5、选择图片,点击上传至服务器,测试上传

连接图片服务器发现目录成功创建,图片成功上传








