返回顶部
首页 > 资讯 > 精选 >SpringBoot如何集成SFTP客户端实现文件上传下载
  • 221
分享到

SpringBoot如何集成SFTP客户端实现文件上传下载

2023-07-06 13:07:04 221人浏览 独家记忆
摘要

这篇文章主要介绍“SpringBoot如何集成SFTP客户端实现文件上传下载”,在日常操作中,相信很多人在springBoot如何集成SFTP客户端实现文件上传下载问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答

这篇文章主要介绍“SpringBoot如何集成SFTP客户端实现文件上传下载”,在日常操作中,相信很多人在springBoot如何集成SFTP客户端实现文件上传下载问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoot如何集成SFTP客户端实现文件上传下载”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

背景

项目开发中,一般文件存储很少再使用SFTP服务,但是也不排除合作伙伴使用SFTP来存储项目中的文件或者通过SFTP来实现文件数据的交互。

我遇到的项目中,就有银行和保险公司等合作伙伴通过SFTP服务来实现与我们项目的文件数据的交互。

为了能够顺利地完成与友商的SFTP服务的连通,我们需要在自己的项目中实现一套SFTP客户端工具。一般我们会采用jsch来实现SFTP客户端。

依赖

<!--执行远程操作--><dependency>    <groupId>com.jcraft</groupId>    <artifactId>jsch</artifactId>    <version>0.1.55</version></dependency>     <!--链接池--><dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-pool2</artifactId>    <version>2.11.1</version></dependency>

首先我们一定要引入jsch依赖,这个是我们实现SFTP客户端的基石;其次我们引入了链接池工具,为了避免每次执行SFTP命令都要重新创建链接,我们使用池化的方式优化了比较消耗资源的创建操作。

创建工具类

为了更好的使用SFTP工具,我们把jsch中关于SFTP的相关功能提炼出来,做了一次简单的封装,做成了我们可以直接使用的工具类。

里面只有两类方法:

创建Session与开启Session;

session创建好后,还不能创建channel,需要开启session后才能创建channel;

创建channel与开启channel;

channel也是一样,创建好的channel需要开启后才能真正地执行命令;

public class JschUtil {    public static Session createSession(String userName, String passWord, String host, int port, String privateKeyFile, String passphrase) throws AwesomeException {    return createSession(new JSch(), userName, password, host, port, privateKeyFile, passphrase);  }    public static Session createSession(JSch jSch, String userName, String password, String host, int port, String privateKeyFile, String passphrase) throws AwesomeException {    try {      if (!StringUtils.isEmpty(privateKeyFile)) {        // 使用密钥验证方式,密钥可以是有口令的密钥,也可以是没有口令的密钥        if (!StringUtils.isEmpty(passphrase)) {          jSch.addIdentity(privateKeyFile, passphrase);        } else {          jSch.addIdentity(privateKeyFile);        }      }      // 获取session      Session session = jSch.getSession(userName, host, port);      if (!StringUtils.isEmpty(password)) {        session.setPassword(password);      }      // 不校验域名      session.setConfig("StrictHosTKEyChecking", "no");      return session;    } catch (Exception e) {      throw new AwesomeException(500, "create session fail");    }  }    public static Session createSession(JSch jSch, String userName, String password, String host, int port) throws AwesomeException {    return createSession(jSch, userName, password, host, port, StringUtils.EMPTY, StringUtils.EMPTY);  }    private Session createSession(JSch jSch, String userName, String host, int port) throws AwesomeException {    return createSession(jSch, userName, StringUtils.EMPTY, host, port, StringUtils.EMPTY, StringUtils.EMPTY);  }    public static Session openSession(JSch jSch, String userName, String password, String host, int port, String privateKeyFile, String passphrase, int timeout) throws AwesomeException {    Session session = createSession(jSch, userName, password, host, port, privateKeyFile, passphrase);    try {      if (timeout >= 0) {        session.connect(timeout);      } else {        session.connect();      }      return session;    } catch (Exception e) {      throw new AwesomeException(500, "session connect fail");    }  }    public static Session openSession(String userName, String password, String host, int port, String privateKeyFile, String passphrase, int timeout) throws AwesomeException {    Session session = createSession(userName, password, host, port, privateKeyFile, passphrase);    try {      if (timeout >= 0) {        session.connect(timeout);      } else {        session.connect();      }      return session;    } catch (Exception e) {      throw new AwesomeException(500, "session connect fail");    }  }    public static Session openSession(JSch jSch, String userName, String password, String host, int port, int timeout) throws AwesomeException {    return openSession(jSch, userName, password, host, port, StringUtils.EMPTY, StringUtils.EMPTY, timeout);  }    public static Session openSession(String userName, String password, String host, int port, int timeout) throws AwesomeException {    return openSession(userName, password, host, port, StringUtils.EMPTY, StringUtils.EMPTY, timeout);  }    public static Session openSession(JSch jSch, String userName, String host, int port, int timeout) throws AwesomeException {    return openSession(jSch, userName, StringUtils.EMPTY, host, port, StringUtils.EMPTY, StringUtils.EMPTY, timeout);  }    public static Session openSession(String userName, String host, int port, int timeout) throws AwesomeException {    return openSession(userName, StringUtils.EMPTY, host, port, StringUtils.EMPTY, StringUtils.EMPTY, timeout);  }    public static Channel createChannel(Session session, ChannelType channelType) throws AwesomeException {    try {      if (!session.isConnected()) {        session.connect();      }      return session.openChannel(channelType.getValue());    } catch (Exception e) {      throw new AwesomeException(500, "open channel fail");    }  }    public static ChannelSftp createSftp(Session session) throws AwesomeException {    return (ChannelSftp) createChannel(session, ChannelType.SFTP);  }    public static Channelshell createShell(Session session) throws AwesomeException {    return (ChannelShell) createChannel(session, ChannelType.SHELL);  }    public static Channel openChannel(Session session, ChannelType channelType, int timeout) throws AwesomeException {    Channel channel = createChannel(session, channelType);    try {      if (timeout >= 0) {        channel.connect(timeout);      } else {        channel.connect();      }      return channel;    } catch (Exception e) {      throw new AwesomeException(500, "connect channel fail");    }  }    public static ChannelSftp openSftpChannel(Session session, int timeout) throws AwesomeException {    return (ChannelSftp) openChannel(session, ChannelType.SFTP, timeout);  }    public static ChannelShell openShellChannel(Session session, int timeout) throws AwesomeException {    return (ChannelShell) openChannel(session, ChannelType.SHELL, timeout);  }  enum ChannelType {    SESSION("session"),    SHELL("shell"),    EXEC("exec"),    X11("x11"),    AGENT_FORWARDING("auth-agent@openssh.com"),    DIRECT_tcpIP("direct-tcpip"),    FORWARDED_TCPIP("forwarded-tcpip"),    SFTP("sftp"),    SUBSYSTEM("subsystem");    private final String value;    ChannelType(String value) {      this.value = value;    }    public String getValue() {      return this.value;    }  }}

SFTP链接池化

我们通过实现BasePooledObjectFactory类来池化通道ChannelSftp。这并不是真正池化的代码,下面的代码只是告知池化管理器如何创建对象和销毁对象。

static class SftpFactory extends BasePooledObjectFactory<ChannelSftp> implements AutoCloseable {    private Session session;    private SftpProperties properties;    // 初始化SftpFactory    // 里面主要是创建目标session,后续可用通过这个session不断地创建ChannelSftp。    SftpFactory(SftpProperties properties) throws AwesomeException {      this.properties = properties;      String username = properties.getUsername();      String password = properties.getPassword();      String host = properties.getHost();      int port = properties.getPort();      String privateKeyFile = properties.getPrivateKeyFile();      String passphrase = properties.getPassphrase();      session = JschUtil.createSession(username, password, host, port, privateKeyFile, passphrase);    }    // 销毁对象,主要是销毁ChannelSftp    @Override    public void destroyObject(PooledObject<ChannelSftp> p) throws Exception {      p.getObject().disconnect();    }    // 创建对象ChannelSftp    @Override    public ChannelSftp create() throws Exception {      int timeout = properties.getTimeout();      return JschUtil.openSftpChannel(this.session, timeout);    }    // 包装创建出来的对象    @Override    public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) {      return new DefaultPooledObject<>(channelSftp);    }    // 验证对象是否可用    @Override    public boolean validateObject(PooledObject<ChannelSftp> p) {      return p.getObject().isConnected();    }    // 销毁资源,关闭session    @Override    public void close() throws Exception {      if (Objects.nonNull(session)) {        if (session.isConnected()) {          session.disconnect();        }        session = null;      }    }  }

为了实现真正的池化操作,我们还需要以下代码:

我们需要在SftpClient对象中创建一个GenericObjectPool对象池,这个才是真正的池子,它负责创建和存储所有的对象。

我们还需要提供资源销毁的功能,也就是实现AutoCloseable,在服务停止时,需要把相关的资源销毁。

public class SftpClient implements AutoCloseable {  private SftpFactory sftpFactory;  GenericObjectPool<ChannelSftp> objectPool;  // 构造方法1  public SftpClient(SftpProperties properties, GenericObjectPoolConfig<ChannelSftp> poolConfig) throws AwesomeException {    this.sftpFactory = new SftpFactory(properties);    objectPool = new GenericObjectPool<>(this.sftpFactory, poolConfig);  }  // 构造方法2  public SftpClient(SftpProperties properties) throws AwesomeException {    this.sftpFactory = new SftpFactory(properties);    SftpProperties.PoolConfig config = properties.getPool();    // 默认池化配置    if (Objects.isNull(config)) {      objectPool = new GenericObjectPool<>(this.sftpFactory);    } else {      // 自定义池化配置      GenericObjectPoolConfig<ChannelSftp> poolConfig = new GenericObjectPoolConfig<>();      poolConfig.setMaxIdle(config.getMaxIdle());      poolConfig.setMaxTotal(config.getMaxTotal());      poolConfig.setMinIdle(config.getMinIdle());      poolConfig.setTestOnBorrow(config.isTestOnBorrow());      poolConfig.setTestOnCreate(config.isTestOnCreate());      poolConfig.setTestOnReturn(config.isTestOnReturn());      poolConfig.setTestWhileIdle(config.isTestWhileIdle());      poolConfig.setBlockWhenExhausted(config.isBlockWhenExhausted());      poolConfig.setMaxWait(Duration.ofMillis(config.getMaxWaitMillis()));      poolConfig.setTimeBetweenEvictionRuns(Duration.ofMillis(config.getTimeBetweenEvictionRunsMillis()));      objectPool = new GenericObjectPool<>(this.sftpFactory, poolConfig);    }  }    // 销毁资源    @Override  public void close() throws Exception {    // 销毁链接池    if (Objects.nonNull(this.objectPool)) {      if (!this.objectPool.isClosed()) {        this.objectPool.close();      }    }    this.objectPool = null;    // 销毁sftpFactory    if (Objects.nonNull(this.sftpFactory)) {      this.sftpFactory.close();    }  }}

SFTP链接池的使用

我们已经对链接池进行了初始化,下面我们就可以从链接池中获取我们需要的ChannelSftp来实现文件的上传下载了。

下面实现了多种文件上传和下载的方式:

直接把本地文件上传到SFTP服务器的指定路径;

把InputStream输入流提交到SFTP服务器指定路径中;

可以针对以上两种上传方式进行进度的监测;

把SFTP服务器中的指定文件下载到本地机器上;

把SFTP服务器˙中的文件写入指定的输出流;

针对以上两种下载方式,监测下载进度;

    public boolean uploadFile(String srcFilePath, String targetDir, String targetFileName) throws AwesomeException {    return uploadFile(srcFilePath, targetDir, targetFileName, null);  }    public boolean uploadFile(String srcFilePath, String targetDir, String targetFileName, SftpProgreSSMonitor monitor) throws AwesomeException {    ChannelSftp channelSftp = null;    try {      // 从链接池获取对象      channelSftp = this.objectPool.borrowObject();      // 如果不存在目标文件夹      if (!exist(channelSftp, targetDir)) {        mkdirs(channelSftp, targetDir);      }      channelSftp.cd(targetDir);      // 上传文件      if (Objects.nonNull(monitor)) {        channelSftp.put(srcFilePath, targetFileName, monitor);      } else {        channelSftp.put(srcFilePath, targetFileName);      }      return true;    } catch (Exception e) {      throw new AwesomeException(500, "upload file fail");    } finally {      if (Objects.nonNull(channelSftp)) {        // 返还对象给链接池        this.objectPool.returnObject(channelSftp);      }    }  }    public boolean uploadFile(InputStream in, String targetDir, String targetFileName) throws AwesomeException {    return uploadFile(in, targetDir, targetFileName, null);  }    public boolean uploadFile(InputStream in, String targetDir, String targetFileName, SftpProgressMonitor monitor) throws AwesomeException {    ChannelSftp channelSftp = null;    try {      channelSftp = this.objectPool.borrowObject();      // 如果不存在目标文件夹      if (!exist(channelSftp, targetDir)) {        mkdirs(channelSftp, targetDir);      }      channelSftp.cd(targetDir);      if (Objects.nonNull(monitor)) {        channelSftp.put(in, targetFileName, monitor);      } else {        channelSftp.put(in, targetFileName);      }      return true;    } catch (Exception e) {      throw new AwesomeException(500, "upload file fail");    } finally {      if (Objects.nonNull(channelSftp)) {        this.objectPool.returnObject(channelSftp);      }    }  }    public boolean downloadFile(String remoteFile, String targetFilePath) throws AwesomeException {    return downloadFile(remoteFile, targetFilePath, null);  }    public boolean downloadFile(String remoteFile, String targetFilePath, SftpProgressMonitor monitor) throws AwesomeException {    ChannelSftp channelSftp = null;    try {      channelSftp = this.objectPool.borrowObject();      // 如果不存在目标文件夹      if (!exist(channelSftp, remoteFile)) {        // 不用下载了        return false;      }      File targetFile = new File(targetFilePath);      try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {        if (Objects.nonNull(monitor)) {          channelSftp.get(remoteFile, outputStream, monitor);        } else {          channelSftp.get(remoteFile, outputStream);        }      }      return true;    } catch (Exception e) {      throw new AwesomeException(500, "upload file fail");    } finally {      if (Objects.nonNull(channelSftp)) {        this.objectPool.returnObject(channelSftp);      }    }  }    public boolean downloadFile(String remoteFile, OutputStream outputStream) throws AwesomeException {    return downloadFile(remoteFile, outputStream, null);  }    public boolean downloadFile(String remoteFile, OutputStream outputStream, SftpProgressMonitor monitor) throws AwesomeException {    ChannelSftp channelSftp = null;    try {      channelSftp = this.objectPool.borrowObject();      // 如果不存在目标文件夹      if (!exist(channelSftp, remoteFile)) {        // 不用下载了        return false;      }      if (Objects.nonNull(monitor)) {        channelSftp.get(remoteFile, outputStream, monitor);      } else {        channelSftp.get(remoteFile, outputStream);      }      return true;    } catch (Exception e) {      throw new AwesomeException(500, "upload file fail");    } finally {      if (Objects.nonNull(channelSftp)) {        this.objectPool.returnObject(channelSftp);      }    }  }    protected boolean mkdirs(ChannelSftp channelSftp, String dir) {    try {      String pwd = channelSftp.pwd();      if (StringUtils.contains(pwd, dir)) {        return true;      }      String relativePath = StringUtils.substringAfter(dir, pwd);      String[] dirs = StringUtils.splitByWholeSeparatorPreserveAllTokens(relativePath, "/");      for (String path : dirs) {        if (StringUtils.isBlank(path)) {          continue;        }        try {          channelSftp.cd(path);        } catch (SftpException e) {          channelSftp.mkdir(path);          channelSftp.cd(path);        }      }      return true;    } catch (Exception e) {      return false;    }  }    protected boolean exist(ChannelSftp channelSftp, String dir) {    try {      channelSftp.lstat(dir);      return true;    } catch (Exception e) {      return false;    }  }

集成到SpringBoot中

我们可以通过java config的方式,把我们已经实现好的SftpClient类实例化到Spring ioc容器中来管理,以便让开发人员在整个项目中通过@Autowired的方式就可以直接使用。

配置
import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Configuration;@Data@Configuration@ConfigurationProperties(prefix = "sftp.config")public class SftpProperties {  // 用户名  private String username;  // 密码  private String password;  // 主机名  private String host;  // 端口  private int port;  // 密钥  private String privateKeyFile;  // 口令  private String passphrase;  // 通道链接超时时间  private int timeout;  // 链接池配置  private PoolConfig pool;  @Data  public static class PoolConfig {    //最大空闲实例数,空闲超过此值将会被销毁淘汰    private int maxIdle;    // 最小空闲实例数,对象池将至少保留2个空闲对象    private int minIdle;    //最大对象数量,包含借出去的和空闲的    private int maxTotal;    //对象池满了,是否阻塞获取(false则借不到直接抛异常)    private boolean blockWhenExhausted;    // BlockWhenExhausted为true时生效,对象池满了阻塞获取超时,不设置则阻塞获取不超时,也可在borrowObject方法传递第二个参数指定本次的超时时间    private long maxWaitMillis;    // 创建对象后是否验证对象,调用objectFactory#validateObject    private boolean testOnCreate;    // 借用对象后是否验证对象 validateObject    private boolean testOnBorrow;    // 归还对象后是否验证对象 validateObject    private boolean testOnReturn;    // 定时检查期间是否验证对象 validateObject    private boolean testWhileIdle;    //定时检查淘汰多余的对象, 启用单独的线程处理    private long timeBetweenEvictionRunsMillis;    //jmx监控,和springboot自带的jmx冲突,可以选择关闭此配置或关闭springboot的jmx配置    private boolean jmxEnabled;  }}
java Bean注入
import com.example.awesomespring.exception.AwesomeException;import com.example.awesomespring.sftp.SftpClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class SftpConfig {  @Autowired  private SftpProperties properties;  // 创建SftpClient对象  @Bean(destroyMethod = "close")  @ConditionalOnProperty(prefix = "sftp.config")  public SftpClient sftpClient() throws AwesomeException {    return new SftpClient(properties);  }}

通过以上代码,我们就可以在项目的任何地方直接使用SFTP客户端来上传和下载文件了。

到此,关于“SpringBoot如何集成SFTP客户端实现文件上传下载”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: SpringBoot如何集成SFTP客户端实现文件上传下载

本文链接: https://lsjlt.com/news/358444.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringBoot如何集成SFTP客户端实现文件上传下载
    这篇文章主要介绍“SpringBoot如何集成SFTP客户端实现文件上传下载”,在日常操作中,相信很多人在SpringBoot如何集成SFTP客户端实现文件上传下载问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-07-06
  • QtQFtp客户端实现上传下载文件
    目录1.简介2.用到的主要类2.1QNetworkReply2.2QNetworkRequest3.示例3.1本地搭建一个FTP服务器。3.2示例1.简介 实现FTP客户端有几种方式...
    99+
    2024-04-02
  • SpringBoot如何实现上传和下载文件
    这篇文章主要介绍SpringBoot如何实现上传和下载文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!技术概述我们的项目是实现一个论坛。在论坛上发布博客时应该要可以上传文件,用户阅读博客是应该要可以下载文件。于是我...
    99+
    2023-06-20
  • Java中http下载文件客户端和上传文件客户端的示例分析
    这篇文章主要介绍了Java中http下载文件客户端和上传文件客户端的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、下载客户端代码package java...
    99+
    2023-05-30
    java http
  • springboot集成ftp实现文件上传
    本文实例为大家分享了springboot集成ftp实现文件上传的具体代码,供大家参考,具体内容如下 1、FileUtil package io.renren.modules.os...
    99+
    2024-04-02
  • SpringBoot集成FastDFS依赖如何实现文件上传
    这篇文章主要介绍SpringBoot集成FastDFS依赖如何实现文件上传,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、引入依赖简单说一下这个依赖部分,目前大部分都是采用的如下依赖:<!-- ht...
    99+
    2023-06-15
  • SpringBoot如何实现文件上传与下载功能
    今天小编给大家分享一下SpringBoot如何实现文件上传与下载功能的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Sprin...
    99+
    2023-07-02
  • SpringBoot 集成MongoDB实现文件上传功能
    目录前言环境代码实现测试源码前言 记录下SpringBoot集成MongoDB实现文件上传的步骤MongoDB - 5.0.6安装包 链接: https://pan.baidu.co...
    99+
    2024-04-02
  • Java如何使用Sftp和Ftp实现对文件的上传和下载
    这篇文章将为大家详细讲解有关Java如何使用Sftp和Ftp实现对文件的上传和下载,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。第一步,导入maven依赖<!-- FTP依赖包 ...
    99+
    2023-06-14
  • HTML5如何实现文件上传下载
    这篇文章主要介绍了HTML5如何实现文件上传下载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言HTML5 中提供的文件API在前端中有着...
    99+
    2024-04-02
  • Django 如何实现文件上传下载
    目录1. 前言 2. 实战一下 2-1  进入虚拟环境,创建一个项目及 App2-2  创建模板目录并配置 settings.py2-3  创...
    99+
    2024-04-02
  • Django如何实现文件上传下载
    小编给大家分享一下Django如何实现文件上传下载,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 前言文件上传、下载作为基础功能,在 Web 项目中非常普遍,...
    99+
    2023-06-14
  • SpringMVC如何实现文件上传下载
    本篇内容主要讲解“SpringMVC如何实现文件上传下载”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringMVC如何实现文件上传下载”吧!一、通用配置pom.xml  ...
    99+
    2023-06-22
  • Java使用Sftp和Ftp实现对文件的上传和下载
    sftp和ftp两种方式区别,还不清楚的,请自行百度查询,此处不多赘述。完整代码地址在结尾!! 第一步,导入maven依赖 <!-- FTP依赖包 --> <...
    99+
    2024-04-02
  • SpringBoot实现文件上传下载功能小结
    最近做的一个项目涉及到文件上传与下载。前端上传采用百度webUploader插件。有关该插件的使用方法还在研究中,日后整理再记录。本文主要介绍SpringBoot后台对文件上传与下载的处理。单文件上传// 单文件上传@RequestMapp...
    99+
    2023-05-31
    spring boot 文件上传
  • Python如何使用sftp实现上传和下载功能
    这篇文章主要介绍了Python如何使用sftp实现上传和下载功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。python可以做什么Python是一种编程语言,内置了许多有效...
    99+
    2023-06-14
  • SpringBoot整合MongoDB实现文件上传下载删除
    目录本文主要内容 1. 基础命令 2. GridFsTemplate使用 2.1引入pom依赖2.2 配置yml2.3 上传下载删除 本文主要内容 MongoDB基础操作...
    99+
    2024-04-02
  • SpringBoot文件上传与下载功能实现详解
    目录前言1、引入Apache Commons FileUpload组件依赖2、设置上传文件大小限制3、创建选择文件视图页面4、创建控制器5、创建文件下载视图页面前言 文件上传与下载是...
    99+
    2022-11-13
    SpringBoot文件上传 SpringBoot文件下载
  • SpringBoot怎么实现文件上传与下载功能
    这篇“SpringBoot怎么实现文件上传与下载功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBoot怎么实...
    99+
    2023-07-06
  • SpringMVC实现上传下载文件
    本文实例为大家分享了SpringMVC实现上传下载文件的具体代码,供大家参考,具体内容如下 一、SpringMVC专门提供了CommonsMultipartResolver组件用于文...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作