当前位置: 代码网 > it编程>编程语言>Java > SpringBoot通过URL地址获取文件的多种方式

SpringBoot通过URL地址获取文件的多种方式

2026年01月12日 Java 我要评论
在spring boot中,可以通过url地址获取文件有多种方式。以下是几种常见的方法:1. 使用 java 原生的 url 和 httpurlconnectionimport java.io.*;i

在spring boot中,可以通过url地址获取文件有多种方式。以下是几种常见的方法:

1. 使用 java 原生的 url 和 httpurlconnection

import java.io.*;
import java.net.httpurlconnection;
import java.net.url;
 
public class urlfiledownloader {
    
    public static void downloadfile(string fileurl, string savepath) throws ioexception {
        url url = new url(fileurl);
        httpurlconnection httpconn = (httpurlconnection) url.openconnection();
        httpconn.setrequestmethod("get");
        
        int responsecode = httpconn.getresponsecode();
        
        if (responsecode == httpurlconnection.http_ok) {
            try (inputstream inputstream = httpconn.getinputstream();
                 fileoutputstream outputstream = new fileoutputstream(savepath)) {
                
                byte[] buffer = new byte[4096];
                int bytesread;
                
                while ((bytesread = inputstream.read(buffer)) != -1) {
                    outputstream.write(buffer, 0, bytesread);
                }
            }
        } else {
            throw new ioexception("http 请求失败,响应码: " + responsecode);
        }
        
        httpconn.disconnect();
    }
}

2. 使用 spring 的 resttemplate

import org.springframework.core.io.resource;
import org.springframework.http.responseentity;
import org.springframework.stereotype.service;
import org.springframework.web.client.resttemplate;
import org.springframework.core.io.filesystemresource;
 
import java.io.file;
import java.io.fileoutputstream;
import java.io.inputstream;
import java.nio.file.files;
import java.nio.file.path;
import java.nio.file.standardcopyoption;
 
@service
public class filedownloadservice {
    
    private final resttemplate resttemplate;
    
    public filedownloadservice(resttemplatebuilder resttemplatebuilder) {
        this.resttemplate = resttemplatebuilder.build();
    }
    
    // 方法1:下载文件到本地
    public file downloadfiletolocal(string fileurl, string localfilepath) throws ioexception {
        responseentity<byte[]> response = resttemplate.getforentity(fileurl, byte[].class);
        
        if (response.getstatuscode().is2xxsuccessful() && response.getbody() != null) {
            file file = new file(localfilepath);
            try (fileoutputstream fos = new fileoutputstream(file)) {
                fos.write(response.getbody());
            }
            return file;
        } else {
            throw new ioexception("文件下载失败");
        }
    }
    
    // 方法2:返回 resource
    public resource downloadfileasresource(string fileurl, string localfilename) throws ioexception {
        responseentity<byte[]> response = resttemplate.getforentity(fileurl, byte[].class);
        
        if (response.getstatuscode().is2xxsuccessful() && response.getbody() != null) {
            path tempfile = files.createtempfile(localfilename, ".tmp");
            files.write(tempfile, response.getbody());
            return new filesystemresource(tempfile.tofile());
        }
        throw new ioexception("文件下载失败");
    }
    
    // 方法3:流式下载大文件
    public file downloadlargefile(string fileurl, string outputpath) throws ioexception {
        return resttemplate.execute(fileurl, httpmethod.get, null, clienthttpresponse -> {
            file file = new file(outputpath);
            try (inputstream inputstream = clienthttpresponse.getbody();
                 fileoutputstream outputstream = new fileoutputstream(file)) {
                
                byte[] buffer = new byte[8192];
                int bytesread;
                while ((bytesread = inputstream.read(buffer)) != -1) {
                    outputstream.write(buffer, 0, bytesread);
                }
            }
            return file;
        });
    }
}

3. 使用 resttemplate 配置类

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.web.client.resttemplate;
import org.springframework.http.client.simpleclienthttprequestfactory;
import org.springframework.boot.web.client.resttemplatebuilder;
import org.springframework.http.converter.bytearrayhttpmessageconverter;
 
import java.time.duration;
 
@configuration
public class resttemplateconfig {
    
    @bean
    public resttemplate resttemplate(resttemplatebuilder builder) {
        return builder
            .setconnecttimeout(duration.ofseconds(30))
            .setreadtimeout(duration.ofseconds(60))
            .additionalmessageconverters(new bytearrayhttpmessageconverter())
            .build();
    }
}

4. 使用 webclient(响应式,spring 5+)

import org.springframework.core.io.resource;
import org.springframework.http.mediatype;
import org.springframework.stereotype.service;
import org.springframework.web.reactive.function.client.webclient;
import reactor.core.publisher.mono;
 
import java.nio.file.path;
import java.nio.file.paths;
 
@service
public class webclientfiledownloadservice {
    
    private final webclient webclient;
    
    public webclientfiledownloadservice(webclient.builder webclientbuilder) {
        this.webclient = webclientbuilder.build();
    }
    
    public mono<resource> downloadfile(string fileurl) {
        return webclient.get()
            .uri(fileurl)
            .accept(mediatype.application_octet_stream)
            .retrieve()
            .bodytomono(resource.class);
    }
    
    public mono<void> downloadtofile(string fileurl, string outputpath) {
        return webclient.get()
            .uri(fileurl)
            .retrieve()
            .bodytomono(byte[].class)
            .flatmap(bytes -> {
                try {
                    path path = paths.get(outputpath);
                    java.nio.file.files.write(path, bytes);
                    return mono.empty();
                } catch (ioexception e) {
                    return mono.error(e);
                }
            });
    }
}

5. 完整的 controller 示例

import org.springframework.core.io.resource;
import org.springframework.core.io.bytearrayresource;
import org.springframework.http.httpheaders;
import org.springframework.http.mediatype;
import org.springframework.http.responseentity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.resttemplate;
 
import java.io.ioexception;
 
@restcontroller
@requestmapping("/api/files")
public class filedownloadcontroller {
    
    private final resttemplate resttemplate;
    private final filedownloadservice filedownloadservice;
    
    public filedownloadcontroller(resttemplate resttemplate, 
                                  filedownloadservice filedownloadservice) {
        this.resttemplate = resttemplate;
        this.filedownloadservice = filedownloadservice;
    }
    
    // 直接返回文件流
    @getmapping("/download")
    public responseentity<resource> downloadfromurl(@requestparam string url) 
            throws ioexception {
        
        responseentity<byte[]> response = resttemplate.getforentity(url, byte[].class);
        
        if (response.getstatuscode().is2xxsuccessful() && response.getbody() != null) {
            bytearrayresource resource = new bytearrayresource(response.getbody());
            
            return responseentity.ok()
                .contenttype(mediatype.application_octet_stream)
                .header(httpheaders.content_disposition, 
                       "attachment; filename=\"" + getfilenamefromurl(url) + "\"")
                .body(resource);
        }
        
        return responseentity.notfound().build();
    }
    
    // 代理下载并保存到服务器
    @postmapping("/proxy-download")
    public responseentity<string> proxydownload(@requestparam string url, 
                                               @requestparam string savepath) {
        try {
            file file = filedownloadservice.downloadfiletolocal(url, savepath);
            return responseentity.ok("文件已保存: " + file.getabsolutepath());
        } catch (ioexception e) {
            return responseentity.badrequest().body("下载失败: " + e.getmessage());
        }
    }
    
    private string getfilenamefromurl(string url) {
        string[] parts = url.split("/");
        return parts[parts.length - 1];
    }
}

6. 添加依赖(maven)

<dependencies>
    <!-- spring boot starter web -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-web</artifactid>
    </dependency>
    
    <!-- webclient 响应式支持 -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-webflux</artifactid>
    </dependency>
</dependencies>

7. 异常处理和优化建议

import org.springframework.web.client.restclientexception;
import org.springframework.web.client.httpclienterrorexception;
import org.springframework.web.client.httpservererrorexception;
 
@service
public class robustfiledownloadservice {
    
    public void downloadwithretry(string fileurl, string outputpath, int maxretries) {
        int retrycount = 0;
        
        while (retrycount < maxretries) {
            try {
                // 下载逻辑
                downloadfile(fileurl, outputpath);
                return;
            } catch (httpclienterrorexception e) {
                // 客户端错误(4xx),通常不需要重试
                throw e;
            } catch (httpservererrorexception | restclientexception e) {
                // 服务器错误(5xx)或网络错误,重试
                retrycount++;
                if (retrycount >= maxretries) {
                    throw e;
                }
                try {
                    thread.sleep(1000 * retrycount); // 指数退避
                } catch (interruptedexception ie) {
                    thread.currentthread().interrupt();
                }
            }
        }
    }
    
    // 设置超时和代理
    public resttemplate resttemplatewithtimeout() {
        simpleclienthttprequestfactory requestfactory = new simpleclienthttprequestfactory();
        requestfactory.setconnecttimeout(5000);
        requestfactory.setreadtimeout(30000);
        
        // 设置代理(如果需要)
        // proxy proxy = new proxy(proxy.type.http, new inetsocketaddress("proxy", 8080));
        // requestfactory.setproxy(proxy);
        
        return new resttemplate(requestfactory);
    }
}

使用示例

@springbootapplication
public class application implements commandlinerunner {
    
    @autowired
    private filedownloadservice filedownloadservice;
    
    public static void main(string[] args) {
        springapplication.run(application.class, args);
    }
    
    @override
    public void run(string... args) throws exception {
        // 下载文件示例
        string fileurl = "https://example.com/path/to/file.pdf";
        string savepath = "/tmp/downloaded-file.pdf";
        
        file downloadedfile = filedownloadservice.downloadfiletolocal(fileurl, savepath);
        system.out.println("文件已下载到: " + downloadedfile.getabsolutepath());
    }
}

注意事项

  1. 网络超时设置:合理设置连接和读取超时
  2. 异常处理:处理网络异常、文件不存在等情况
  3. 大文件处理:使用流式处理避免内存溢出
  4. 安全性:验证url,防止ssrf攻击
  5. 资源清理:确保流正确关闭
  6. 并发控制:大量下载时考虑使用连接池
  7. 文件类型验证:验证下载的文件类型是否符合预期

选择哪种方法取决于具体需求:

  • 简单场景:使用 httpurlconnection
  • spring boot项目:使用 resttemplate
  • 响应式编程:使用 webclient
  • 大文件下载:使用流式处理

以上就是springboot通过url地址获取文件的多种方式的详细内容,更多关于springboot url地址获取文件的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com