欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

前端發(fā)送的請(qǐng)求Spring如何返回一個(gè)文件詳解

 更新時(shí)間:2024年09月04日 09:23:05   作者:不能再留遺憾了  
這篇文章主要給大家介紹了關(guān)于前端發(fā)送的請(qǐng)求Spring如何返回一個(gè)文件的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

因?yàn)楸救酥饕菍W(xué)習(xí)后端Java的,前端呢只是了解一點(diǎn)點(diǎn)基礎(chǔ)語法,所以本篇文章中可能會(huì)顯得有一些不專業(yè),所以呢,請(qǐng)大家多多包涵。

對(duì)于前后端交互的部分,我使用的最多的就是通過 Ajax 來像后端發(fā)送 HTTP 請(qǐng)求,但是呢,眾所周知,Ajax 默認(rèn)是不直接支持文件的下載的(即,它不能直接觸發(fā)瀏覽器的下載管理器),,你通常需要將文件內(nèi)容作為某種形式的數(shù)據(jù)(如Base64編碼的字符串或Blob)返回,并在前端處理這些數(shù)據(jù)以觸發(fā)下載或顯示文件內(nèi)容。

那么這篇文章,我將介紹如何對(duì)后端即將傳輸?shù)奈募鎏幚?,以至于我們的前端能夠得到這個(gè)文件。

如果文件可以通過URL訪問

如果我們要上傳的問價(jià)可以通過 URL 訪問的話,那么我們就可以使用 UrlResource 來對(duì)文件進(jìn)行處理:

import org.springframework.core.io.Resource;  
import org.springframework.core.io.UrlResource;  
import org.springframework.http.HttpHeaders;  
import org.springframework.http.MediaType;  
import org.springframework.http.ResponseEntity;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RequestParam;  
import org.springframework.web.bind.annotation.RestController;  
 
import java.net.MalformedURLException;  
import java.nio.file.Paths;  
 
@RestController  
public class FileDownloadController {  
 
    @GetMapping("/download")  
    public ResponseEntity<Resource> downloadFile(@RequestParam String fileName) throws MalformedURLException {  
        // 假設(shè)文件存儲(chǔ)在服務(wù)器上的某個(gè)目錄  
        String filePath = "/path/to/your/files/" + fileName;  
        Resource file = new UrlResource(filePath);  
 
        if (file.exists() || file.isReadable()) {  
            // 設(shè)置HTTP頭以支持文件下載  
            HttpHeaders headers = new HttpHeaders();  
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"");  
            headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");  
            headers.add(HttpHeaders.PRAGMA, "no-cache");  
            headers.add(HttpHeaders.EXPIRES, "0");  
 
            return ResponseEntity.ok()  
                    .headers(headers)  
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)  
                    .body(file);  
        } else {  
            // 處理文件不存在或不可讀的情況  
            return ResponseEntity.notFound().build();  
        }  
    }  
}
  • 設(shè)置了Content-Disposition為attachment,這通常用于提示瀏覽器將響應(yīng)作為文件下載。但是,如果你希望圖片直接在瀏覽器中顯示,可能不需要這個(gè)設(shè)置。
  • CACHE_CONTROL 這個(gè)請(qǐng)求頭就是緩存控制
  • expires 過期時(shí)間

注意我們這個(gè)類的返回類型需是 ResponseEntity<>,該類用于構(gòu)建 HTTP 響應(yīng)。響應(yīng)中的 contentType 用來設(shè)置我們返回的 body 是什么類型,MediaType 類中有很多的靜態(tài)類型:

public class MediaType extends MimeType implements Serializable {
    private static final long serialVersionUID = 2069937152339670231L;
    public static final MediaType ALL = new MediaType("*", "*");
    public static final String ALL_VALUE = "*/*";
    public static final MediaType APPLICATION_ATOM_XML = new MediaType("application", "atom+xml");
    public static final String APPLICATION_ATOM_XML_VALUE = "application/atom+xml";
    public static final MediaType APPLICATION_CBOR = new MediaType("application", "cbor");
    public static final String APPLICATION_CBOR_VALUE = "application/cbor";
    public static final MediaType APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded");
    public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded";
    public static final MediaType APPLICATION_GRAPHQL = new MediaType("application", "graphql+json");
    public static final String APPLICATION_GRAPHQL_VALUE = "application/graphql+json";
    public static final MediaType APPLICATION_JSON = new MediaType("application", "json");
    public static final String APPLICATION_JSON_VALUE = "application/json";
    /** @deprecated */
    @Deprecated
    public static final MediaType APPLICATION_JSON_UTF8;
    /** @deprecated */
    @Deprecated
    public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";
    public static final MediaType APPLICATION_OCTET_STREAM;
    public static final String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
    public static final MediaType APPLICATION_PDF;
    public static final String APPLICATION_PDF_VALUE = "application/pdf";
    public static final MediaType APPLICATION_PROBLEM_JSON;
    public static final String APPLICATION_PROBLEM_JSON_VALUE = "application/problem+json";
    /** @deprecated */
    @Deprecated
    public static final MediaType APPLICATION_PROBLEM_JSON_UTF8;
    /** @deprecated */
    @Deprecated
    public static final String APPLICATION_PROBLEM_JSON_UTF8_VALUE = "application/problem+json;charset=UTF-8";
    public static final MediaType APPLICATION_PROBLEM_XML;
    public static final String APPLICATION_PROBLEM_XML_VALUE = "application/problem+xml";
    public static final MediaType APPLICATION_RSS_XML;
    public static final String APPLICATION_RSS_XML_VALUE = "application/rss+xml";
    public static final MediaType APPLICATION_NDJSON;
    public static final String APPLICATION_NDJSON_VALUE = "application/x-ndjson";
    /** @deprecated */
    @Deprecated
    public static final MediaType APPLICATION_STREAM_JSON;
    /** @deprecated */
    @Deprecated
    public static final String APPLICATION_STREAM_JSON_VALUE = "application/stream+json";
    public static final MediaType APPLICATION_XHTML_XML;
    public static final String APPLICATION_XHTML_XML_VALUE = "application/xhtml+xml";
    public static final MediaType APPLICATION_XML;
    public static final String APPLICATION_XML_VALUE = "application/xml";
    public static final MediaType IMAGE_GIF;
    public static final String IMAGE_GIF_VALUE = "image/gif";
    public static final MediaType IMAGE_JPEG;
    public static final String IMAGE_JPEG_VALUE = "image/jpeg";
    public static final MediaType IMAGE_PNG;
    public static final String IMAGE_PNG_VALUE = "image/png";
    public static final MediaType MULTIPART_FORM_DATA;
    public static final String MULTIPART_FORM_DATA_VALUE = "multipart/form-data";
    public static final MediaType MULTIPART_MIXED;
    public static final String MULTIPART_MIXED_VALUE = "multipart/mixed";
    public static final MediaType MULTIPART_RELATED;
    public static final String MULTIPART_RELATED_VALUE = "multipart/related";
    public static final MediaType TEXT_EVENT_STREAM;
    public static final String TEXT_EVENT_STREAM_VALUE = "text/event-stream";
    public static final MediaType TEXT_HTML;
    public static final String TEXT_HTML_VALUE = "text/html";
    public static final MediaType TEXT_MARKDOWN;
    public static final String TEXT_MARKDOWN_VALUE = "text/markdown";
    public static final MediaType TEXT_PLAIN;
    public static final String TEXT_PLAIN_VALUE = "text/plain";
    public static final MediaType TEXT_XML;
    public static final String TEXT_XML_VALUE = "text/xml";
    private static final String PARAM_QUALITY_FACTOR = "q";
}

大家可以根據(jù)自己要返回的文件的具體類型來選擇。

后端對(duì)文件進(jìn)行處理了之后,前端也是需要做出調(diào)整的,由于 Ajax 默認(rèn)不支持文件的下載,所以我們選擇使用 fetch 來作為 web api。

什么是fetch

這里的解釋來自于百度:

fetch 是 Web API 的一部分,它提供了一種簡單、邏輯清晰的方式來跨網(wǎng)絡(luò)異步獲取資源(包括文件、網(wǎng)絡(luò)請(qǐng)求等)。fetch API 返回一個(gè) Promise,這個(gè) Promise 解析為一個(gè) Response 對(duì)象,該對(duì)象包含來自服務(wù)器的各種響應(yīng)信息,比如響應(yīng)頭、狀態(tài)碼等,并且允許你訪問響應(yīng)體(response body)的內(nèi)容。

與 XMLHttpRequest 相比,fetch 提供了一個(gè)更現(xiàn)代、更簡潔的API來訪問和操作網(wǎng)絡(luò)請(qǐng)求和響應(yīng)。fetch 支持 Promise API,這使得異步邏輯更加容易編寫和理解。

fetch 處理文件更加的方便,所以這里我們選擇使用 fetch。

function downloadFile(url, fileName) {  
    fetch(url, {  
        method: 'post', 
        // 可以添加其他必要的請(qǐng)求頭,如認(rèn)證信息等  
        headers: {  
            // 示例:'Authorization': 'Bearer your_token_here'  
        },  
        // 告訴瀏覽器我們期望的響應(yīng)類型是一個(gè)Blob  
        responseType: 'blob'  
    })  
    .then(response => {  
        // 檢查響應(yīng)是否成功  
        if (!response.ok) {  
            throw new Error('Network response was not ok');  
        }  
        // 返回Blob對(duì)象  
        return response.blob();  
    })  
    .then(blob => {  
        // 創(chuàng)建一個(gè)指向該Blob的URL  
        // 我們可以通過這個(gè)生成的URL訪問到這個(gè)文件
        const url = window.URL.createObjectURL(blob); 
  
  		// 我這里就直接將圖片的URL給用了
        let pic = document.querySelector('.main .left .user .picture')
        pic.style.backgroundImage = 'url(' + url + ')' 
  
  		// 這個(gè)用于將生成的URL給清除掉,我們這里可以先不清,
  		//如果清除了的話,前端可能無法通過這個(gè)URL獲取到這個(gè)文件,
  		//我們可以在關(guān)閉頁面的時(shí)候調(diào)用這個(gè)方法
        // 清理工作  
        // window.URL.revokeObjectURL(url);  
    })  
    .catch(error => {  
        console.error('There has been a problem with your fetch operation:', error);  
    });  
} 

如果文件無法通過URL訪問到

如果文件不是通過URL訪問到的,例如它們存儲(chǔ)在文件系統(tǒng)中的話,就需要依靠 FileSystemResource 等其他資源類。

@RequestMapping("/getUserPic")
public ResponseEntity<Resource> getUserPic(String fileName) {
    //獲取到存儲(chǔ)在文件系統(tǒng)中的文件
    Resource resource = new FileSystemResource(Constant.path + fileName);
    return ResponseEntity.ok()
            .contentType(MediaType.IMAGE_JPEG)
            .header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=" + resource.getFilename())
            .body(resource);}

然后前端呢就還是通過 fetch 來為文件創(chuàng)建一個(gè)指向該文件的URL,就可以通過這個(gè)URL訪問了。

如果使用了AOP對(duì)返回結(jié)果做了處理

如果我們的Spring使用了AOP來對(duì)返回結(jié)果進(jìn)行了統(tǒng)一處理的話,對(duì)于返回的 ResponseEntity<> 我們還需要做出調(diào)整:

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    	//調(diào)整在這里,如果返回的類型是Resource的時(shí)候就直接返回
        if (body instanceof Resource) {
            return body;
        }
        if (body instanceof String) {
            try {
                return objectMapper.writeValueAsString(body);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }else if (body instanceof Result) {
            return body;
        }else {
            return Result.success(body);
        }
    }
}

總結(jié) 

到此這篇關(guān)于前端發(fā)送的請(qǐng)求Spring如何返回一個(gè)文件的文章就介紹到這了,更多相關(guān)前端發(fā)送請(qǐng)求Spring返回文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot?加載本地jar到maven的實(shí)現(xiàn)方法

    springboot?加載本地jar到maven的實(shí)現(xiàn)方法

    如何在SpringBoot項(xiàng)目中加載本地jar到Maven本地倉庫,使用Maven的install-file目標(biāo)來實(shí)現(xiàn),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • SpringBoot如何實(shí)現(xiàn)緩存預(yù)熱

    SpringBoot如何實(shí)現(xiàn)緩存預(yù)熱

    緩存預(yù)熱是指在 Spring Boot 項(xiàng)目啟動(dòng)時(shí),預(yù)先將數(shù)據(jù)加載到緩存系統(tǒng)(如 Redis)中的一種機(jī)制,本文主要介紹了SpringBoot如何實(shí)現(xiàn)緩存預(yù)熱,感興趣的可以了解下
    2024-12-12
  • Java fastjson解析json字符串實(shí)現(xiàn)過程解析

    Java fastjson解析json字符串實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Java fastjson解析json字符串實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java?Web中Ajax技術(shù)使用方法介紹

    Java?Web中Ajax技術(shù)使用方法介紹

    ajax技術(shù)是使頁面能局部刷新的一種技術(shù),下面這篇文章主要給大家介紹了關(guān)于JavaWeb之Ajax的基本使用與實(shí)戰(zhàn)案例的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • SpringBoot整合Redis的哨兵模式的實(shí)現(xiàn)

    SpringBoot整合Redis的哨兵模式的實(shí)現(xiàn)

    Redis提供了哨兵模式來處理主從切換和故障轉(zhuǎn)移,本文主要介紹了SpringBoot整合Redis的哨兵模式的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • Java的位圖和布隆過濾器深入詳細(xì)講解

    Java的位圖和布隆過濾器深入詳細(xì)講解

    這篇文章主要介紹了Java的位圖和布隆過濾器,在學(xué)習(xí)之前的數(shù)據(jù)結(jié)構(gòu)的時(shí)候,我們使用的數(shù)據(jù)量都不是很大,但是在生活中,我們常常面臨著要處理大量數(shù)據(jù)結(jié)果并得出最終結(jié)果,那么有沒有什么數(shù)據(jù)結(jié)構(gòu)可以幫助我們實(shí)現(xiàn)這樣的功能呢,想要繼續(xù)了解的朋友可以參考下
    2024-10-10
  • 如何理解和運(yùn)用ClassLoader

    如何理解和運(yùn)用ClassLoader

    這篇文章主要介紹了如何理解和運(yùn)用 ClassLoader,幫助大家更好的理解和使用JVM,感興趣的朋友可以了解下
    2021-01-01
  • Spring Data JPA實(shí)現(xiàn)分頁P(yáng)ageable的實(shí)例代碼

    Spring Data JPA實(shí)現(xiàn)分頁P(yáng)ageable的實(shí)例代碼

    本篇文章主要介紹了Spring Data JPA實(shí)現(xiàn)分頁P(yáng)ageable的實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • Java設(shè)計(jì)模式之組合模式的示例詳解

    Java設(shè)計(jì)模式之組合模式的示例詳解

    組合模式,又叫部分整體模式,它創(chuàng)建了對(duì)象組的數(shù)據(jù)結(jié)構(gòu)組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的訪問具有一致性。本文將通過示例為大家詳細(xì)介紹一下組合模式,需要的可以參考一下
    2022-03-03
  • java使用URLDecoder和URLEncoder對(duì)中文字符進(jìn)行編碼和解碼

    java使用URLDecoder和URLEncoder對(duì)中文字符進(jìn)行編碼和解碼

    這篇文章主要介紹了java 使用 URLDecoder 和 URLEncoder 對(duì)中文字符進(jìn)行編碼和解碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論