Springboot 通过Ftp协议下载文件,并在Vue平台上显示其内容

一、创建Docker镜像

docker pull vsftpd

二、创建Docker容器

docker run -d -p 20:20 -p 21:21 -p 21100-21110:21100-21110 \
-v /home/ftp:/home/vsftpd -e FTP_USER=ftpUsr -e FTP_PASS=123456 \
-e PASV_ADDRESS=192.168.0.10 -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21110 \
--name vsftpd --restart=always fauria/vsftpd

三、配置maven插件

<dependency>
     <groupId>commons-net</groupId>
     <artifactId>commons-net</artifactId>
</dependency>

四、设置工程的配置项

user:
  document-host: 192.168.0.105
  document-ftp-port: 21
  document-ftp-username: ftpUsr
  document-ftp-password: 123456
  document-path: /document
  #回显地址
  document-ftp-httpPath: ftp://192.168.0.105
@Component
@ConfigurationProperties(prefix = "user")
@Data
public class UserConfig {

	private String documentHost;

	private String documentFtpPort;

	private String documentFtpUsername;

	private String documentFtpPassword;

	private String documentPath;

	private String documentFtpHttpPath;

}

五、连接到FTP

private FTPClient connectFtpServer() {
		// 创建FTPClient对象(对于连接ftp服务器,以及上传和上传都必须要用到一个对象)
		FTPClient ftpClient = new FTPClient();
		// 设置连接超时时间
		ftpClient.setConnectTimeout(1000 * 30);
		// 设置ftp字符集
		ftpClient.setControlEncoding("utf-8");
		// 设置被动模式,文件传输端口设置,否则文件上传不成功,也不报错
		ftpClient.enterLocalPassiveMode();
		try {
			// 定义返回的状态码
			int replyCode;
			// 连接ftp(当前项目所部署的服务器和ftp服务器之间可以相互通讯,表示连接成功)
//			ftpClient.connect(userConfig.getDocumentHost());
			if (StringUtils.isBlank(userConfig.getDocumentFtpPort())) {
				ftpClient.connect(userConfig.getDocumentHost());
			} else {
				ftpClient.connect(userConfig.getDocumentHost(), Integer.parseInt(userConfig.getDocumentFtpPort()));
			}
			// 输入账号和密码进行登录
			ftpClient.login(userConfig.getDocumentFtpUsername(), userConfig.getDocumentFtpPassword());
			//切换目录
			ftpClient.changeWorkingDirectory(userConfig.getDocumentPath());
			// 接受状态码(如果成功,返回230,如果失败返回503)
			replyCode = ftpClient.getReplyCode();
			// 根据状态码检测ftp的连接,调用isPositiveCompletion(reply)-->如果连接成功返回true,否则返回false
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				log.info("connect ftp {} failed", userConfig.getDocumentHost());
//				说明连接失败,需要断开连接
				ftpClient.disconnect();
				return null;
			}
			log.info("replyCode:" + replyCode);
		} catch (IOException e) {
			log.error("connect fail:" + e.toString());
			return null;
		}
		return ftpClient;
	}

六、判断文件是否存在

FTPFile[] li = ftp.listFiles(fileName);
Boolean b = (li !=null) && (li.length >0);

七、下载文件核心代码

public void downloadDocument(String filename, OutputStream out) {
		FTPClient ftp = connectFtpServer();
		try{
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftp.enterLocalPassiveMode();
			ftp.retrieveFile(filename, out);
			ftp.logout();
		} catch (Exception e) {
			log.error("FTP文件下载失败!" + e.toString());
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
					log.error(ioe.toString());
				}
			}
		}
	}

或:

public void downloadDocument(String filename, OutputStream out) {
		FTPClient ftp = connectFtpServer();
		try{
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftp.enterLocalPassiveMode();

            /* 控制流量,从而控制下载速度 */
			InputStream is = null;
			is  = ftp.retrieveFileStream(filename);
			byte[] buffer = new byte[1024];
			int len = is.read(buffer);
			while (len != -1) {
				out.write(buffer, 0, len);
				len = is.read(buffer);
			}
			is.close();

			ftp.logout();
		} catch (Exception e) {
			log.error("FTP文件下载失败!" + e.toString());
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
					log.error(ioe.toString());
				}
			}
		}
	}

八、VUE 展示其内容于页面上

<template>
<div>
  <Table class="Ttable"
    border
    :columns="columnData"
    :data="datas"
    :ellipsis="true"
    :loading="tableLoading"
  >
    <Tooltip
        slot-scope="{ row, index }"
        slot="action"
        content="点击显示文件内容"
        transfer
    >
      <Icon
          type="md-list-box"
          :size="24"
          @click="showDocument(row)"
      />
    </Tooltip>
    <Page v-if="pageObj.total >1"
          :total.sync="pageObj.total"
          :current="pageObj.pageIndex"
          :page-size="pageObj.pageSize"
          transfer
          show-total show-sizer
          :styles="{marginLeft:'14px'}"
          @on-change="changPage"
          @on-page-size-change="changPageSize"
    />
  </Table>
  <Modal v-model="showDocumentModal" footer-hide width="80%" :mask-closable="false" >
    <dl v-html="doccumentHtml" />
    <Affix slot="close" ref="documentCloserRef" offset-top="88" :style="{scrollLeft:'92% !important'}" >
      <Tooltip content="关闭"  >
        <Icon :color="'#ff9900'" size="40" type="ios-close-circle" />
      </Tooltip>
    </Affix>
  </Modal>
</div>
</template>

<script>
import {StringUtils} from "@/libs/StringUtil";

export default {
  name: "ProceedingsDocuments",
  components: {},
  data(){
    return{
      datas:[],
      /**
       * 表头
       */
      columnData:[
        {
          title: "序号",
          type: 'index',
          width: 100,
          align: 'center',
          sortable: true,
          className: "table-column-middle",
        },
       {【其他业务字段】},
        {
          title: "详情",
          slot: "action",
          align: "center",
        },
      ],
      tableLoading:false,
      /**
       * 分页参数
       */
      pageObj:{
        total:0,
        pageSize:10,
        pageIndex:1,
      },
      showDocumentModal: false,
      doccumentHtml: ''
    }
  },
  methods:{
    【……】,
    /**
     * 打开文书
     */
    showDocument(rowInfo) {
      let _this = this;
      let documentId = '';
      if(rowInfo!=null && (rowInfo.documentId!=null) ){
        documentId = rowInfo.documentId;
      }
      if(StringUtils.isNotEmpty(rowkey) && (rowInfo.documentExistence)){
        this.$api.postDownloadFile('/data/punishment/document',{documentId},function (resp){
          var reader = new FileReader();
          reader.onload = function(event){
            var content = reader.result;//内容就在这里
            let pureContent = _this.purifyContent(content);
            _this.doccumentHtml = pureContent;
            _this.$set(_this.$refs.documentCloserRef.styles,'left','89%');
            _this.$nextTick(()=>{
              _this.showDocumentModal = true;
            });
          };
          reader.readAsText(resp);
        },e=>{
          console.error(e);
        });
      }else{
        this.$message.warning('对不起,无法将文件打开。');
      }
    },
    purifyContent(content) {
      let pureContent = '';
      try {
        【对文档的内容的后续整理】
      } catch (e) {
        console.error(e);
      }
      return pureContent;
    },
  },
  mounted() {
    ……;
  }
}
</script>

<style scoped>
.Ttable {
  color: #515a6e;
  text-align: center;
  width: 1047px;
}
</style>

上一篇:springboot FTP上传


下一篇:java 实现文件压缩后上床ftp服务器