ElementUI+SpringBoot上传图片文件至VSFTP图片服务器

Java工具 潘老师 1个月前 (10-20) 178 ℃ (0) 扫码查看

基于目前商城项目的开发,需要将图片上传至Nginx+VSFTP搭建的图片服务器,如果你只想了解如何使用java实现将图片等文件上传至VSFTP服务器,可以直接参考相关上传代码即可,要不然看起来会有点复杂,因为涉及到多服务器、存在跨域问题,以下是关于本案例的一些说明:
1、前端是基于Vue+ElementUI,后端是基于SpringBoot
2、前后端分离,前端项目放在81端口的Nginx服务器上,后端项目部署在8080端口的tomcat服务器上
3、Nginx+VSFTP搭建的图片服务器是在ip为192.168.223.128的Linux虚拟机上,关于其搭建可参考:

Nginx+VSFTP搭建图片服务器流程详解

一、前期准备 1、环境准备:我这里使用的是CentOS7 64位Linux操作系统 2、安装与配置Nginx服 […]

1、前端准备

参考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;
}

2、后端准备

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、选择图片,点击上传至服务器,测试上传
ElementUI+SpringBoot上传图片文件至VSFTP图片服务器
连接图片服务器发现目录成功创建,图片成功上传
ElementUI+SpringBoot上传图片文件至VSFTP图片服务器


版权声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系潘老师进行处理。
喜欢 (7)
请潘老师喝杯Coffee吧!】
分享 (0)

您必须 微信登录 才能发表评论!

登录