最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot通過URL地址獲取文件的多種方式

 更新時(shí)間:2026年01月12日 09:59:23   作者:悟能不能悟  
本文介紹了多種在SpringBoot中通過URL地址獲取文件的方法,包括Java原生、RestTemplate、WebClient等,并提供了詳細(xì)的步驟和示例代碼,同時(shí),還討論了異常處理、資源清理、并發(fā)控制等優(yōu)化建議,需要的朋友可以參考下

在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 請(qǐng)求失敗,響應(yīng)碼: " + 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(響應(yīng)式,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();
    }
    
    // 代理下載并保存到服務(wù)器
    @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 響應(yīng)式支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
</dependencies>

7. 異常處理和優(yōu)化建議

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) {
                // 客戶端錯(cuò)誤(4xx),通常不需要重試
                throw e;
            } catch (HttpServerErrorException | RestClientException e) {
                // 服務(wù)器錯(cuò)誤(5xx)或網(wǎng)絡(luò)錯(cuò)誤,重試
                retryCount++;
                if (retryCount >= maxRetries) {
                    throw e;
                }
                try {
                    Thread.sleep(1000 * retryCount); // 指數(shù)退避
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
    
    // 設(shè)置超時(shí)和代理
    public RestTemplate restTemplateWithTimeout() {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(5000);
        requestFactory.setReadTimeout(30000);
        
        // 設(shè)置代理(如果需要)
        // 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());
    }
}

注意事項(xiàng)

  1. 網(wǎng)絡(luò)超時(shí)設(shè)置:合理設(shè)置連接和讀取超時(shí)
  2. 異常處理:處理網(wǎng)絡(luò)異常、文件不存在等情況
  3. 大文件處理:使用流式處理避免內(nèi)存溢出
  4. 安全性:驗(yàn)證URL,防止SSRF攻擊
  5. 資源清理:確保流正確關(guān)閉
  6. 并發(fā)控制:大量下載時(shí)考慮使用連接池
  7. 文件類型驗(yàn)證:驗(yàn)證下載的文件類型是否符合預(yù)期

選擇哪種方法取決于具體需求:

  • 簡(jiǎn)單場(chǎng)景:使用 HttpURLConnection
  • Spring Boot項(xiàng)目:使用 RestTemplate
  • 響應(yīng)式編程:使用 WebClient
  • 大文件下載:使用流式處理

以上就是SpringBoot通過URL地址獲取文件的多種方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot URL地址獲取文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Mybatis分頁插件PageHelper手寫實(shí)現(xiàn)示例

    Mybatis分頁插件PageHelper手寫實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了Mybatis分頁插件PageHelper手寫實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java如何基于反射獲取對(duì)象屬性信息

    Java如何基于反射獲取對(duì)象屬性信息

    這篇文章主要介紹了Java如何基于反射獲取對(duì)象屬性信息,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • springboot+idea熱啟動(dòng)設(shè)置方法(自動(dòng)加載)

    springboot+idea熱啟動(dòng)設(shè)置方法(自動(dòng)加載)

    這篇文章主要介紹了springboot+idea熱啟動(dòng)設(shè)置方法(自動(dòng)加載),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • java面試中經(jīng)常會(huì)問到的mysql問題有哪些總結(jié)(基礎(chǔ)版)

    java面試中經(jīng)常會(huì)問到的mysql問題有哪些總結(jié)(基礎(chǔ)版)

    MySQL作為常見的數(shù)據(jù)庫技術(shù),其掌握程度往往是評(píng)估候選人綜合能力的重要組成部分,下面這篇文章主要介紹了java面試中經(jīng)常會(huì)問到的mysql問題有哪些的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-10-10
  • 詳解SpringBoot接收參數(shù)的五種形式

    詳解SpringBoot接收參數(shù)的五種形式

    在Spring Boot中,接收參數(shù)可以通過多種方式實(shí)現(xiàn),本文給大家介紹了SpringBoot接收參數(shù)的五種形式,并通過代碼和圖文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • springcloud?如何解決微服務(wù)之間token傳遞問題

    springcloud?如何解決微服務(wù)之間token傳遞問題

    這篇文章主要介紹了springcloud?如何解決微服務(wù)之間token傳遞問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot自動(dòng)配置實(shí)現(xiàn)的詳細(xì)步驟

    SpringBoot自動(dòng)配置實(shí)現(xiàn)的詳細(xì)步驟

    這篇文章主要為大家介紹了SpringBoot自動(dòng)配置實(shí)現(xiàn)詳細(xì)的過程步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • SpringCloud Sleuth實(shí)現(xiàn)分布式請(qǐng)求鏈路跟蹤流程詳解

    SpringCloud Sleuth實(shí)現(xiàn)分布式請(qǐng)求鏈路跟蹤流程詳解

    這篇文章主要介紹了SpringCloud Sleuth實(shí)現(xiàn)分布式請(qǐng)求鏈路跟蹤流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-11-11
  • java 取模與取余的區(qū)別說明

    java 取模與取余的區(qū)別說明

    這篇文章主要介紹了java 取模與取余的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Spring-Boot中如何使用多線程處理任務(wù)方法

    Spring-Boot中如何使用多線程處理任務(wù)方法

    這篇文章主要介紹了Spring-Boot中如何使用多線程處理任務(wù)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01

最新評(píng)論

吉安县| 浮山县| 沁阳市| 铅山县| 连南| 公主岭市| 康乐县| 大厂| 扎囊县| 翁牛特旗| 清流县| 区。| 达拉特旗| 霍山县| 郧西县| 五常市| 山西省| 邵武市| 肇州县| 焉耆| 湖州市| 嘉鱼县| 保康县| 山东省| 出国| 个旧市| 宜良县| 班戈县| 凯里市| 瑞安市| 运城市| 南溪县| 四平市| 井陉县| 天津市| 洛宁县| 永寿县| 昆明市| 昆山市| 溆浦县| 广河县|