首頁  >  文章  >  Java  >  如何透過Spring Boot實現檔案與儲存服務

如何透過Spring Boot實現檔案與儲存服務

PHPz
PHPz原創
2023-06-22 12:26:30913瀏覽

隨著互聯網技術的發展,文件和儲存服務已成為各類應用的必要組成部分,其中Spring Boot作為一款快速構建企業級Java應用的框架,在實現文件和存儲服務方面也有著得天獨厚的優勢。本文將介紹如何透過Spring Boot實現檔案和儲存服務。

一、Spring Boot中檔案處理

Spring Boot提供了一套檔案處理方式,透過Spring的Resource和ResourceLoader接口,我們可以取得到本機檔案、classpath下的檔案、網絡資源等。

1.1 本機檔案操作

在Spring Boot開發過程中,我們使用ResourceLoader介面的getResource方法就可以得到指定檔案的Resource對象,程式碼範例如下:

@ResourceLoader
ResourceLoader resourceLoader;

File file = new File("D:/image.jpg"); //指定文件路径(绝对路径)
Resource resource = resourceLoader.getResource("file:" + file.getAbsolutePath()); //获取文件Resource对象
InputStream inputStream = resource.getInputStream(); //获取文件输入流

其中,ResourceLoader為Spring提供的資源載入器接口,可以透過標註@ResourceLoader註解,透過Autowired方式自動注入其實作類別的實例。 getResource()方法用於取得指定檔案路徑的Resource對象,此處我們透過"file:"協定指定絕對路徑。

1.2 classpath檔案操作

在Spring Boot應用程式中,我們可以把Web工程相關的資源檔案(如設定檔)放在classpath下,透過ClassPathResource取得Resource引用,程式碼範例如下:

ClassPathResource classPathResource = new ClassPathResource("config.properties"); //获取配置文件Resource对象
InputStream inputStream = classPathResource.getInputStream(); //获取配置文件输入流

ClassPathResource類別在載入來自應用程式類別路徑的資源時,支援帶檔案系統前綴,如"classpath:"和"file:",此程式碼示範當它沒有指定時,使用與預設的路徑前綴"file:"相關的檔案系統前綴。

1.3 網路檔案操作

除了本地和classpath路徑下的檔案外,Spring Boot還可以透過URLResource物件來操作網路上的文件,程式碼範例如下:

String url = "http://img.iplaysoft.com/wp-content/uploads/2019/free-images/free_stock_photo.jpg";
Resource resource = new UrlResource(url); //获取网络资源Resource对象
InputStream inputStream = resource.getInputStream(); //获取网络资源输入流

其中,UrlResource類別可以實現從網路上取得資源文件,需要傳入網路位址URL作為建構函數的參數。

二、Spring Boot中檔案上傳

在實際的Spring Boot應用程式開發中,檔案上傳是一種常見的需求,在Spring Boot中我們可以使用MultipartFile類別和MultipartResolver解析器來完成文件上傳操作。

2.1 MultipartFile類別

Spring的MultipartFile類別提供了一種簡單且一致的方式來上傳一個或多個檔案。它是@RequestParam註解下使用的MVC處理方法的參數類型,如:

@PostMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file) {
    //具体文件上传操作
    return "success";
}

在上傳檔案時,需要指定具體上傳操作,並設定檔案儲存路徑等相關參數,程式碼範例如下:

@PostMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file) {
    // 获取文件名
    String fileName = file.getOriginalFilename();
    // 设置保存路径
    String filePath = "D:/upload/";
    File dest = new File(filePath + fileName);
    try {
        file.transferTo(dest);
        // 具体业务操作
        return "success";
    } catch (IOException e) {
        e.printStackTrace();
        return "failure";
    }
}

2.2 MultipartResolver解析器

MultipartResolver是一個Spring MVC框架中的接口,用於解析POST請求中的文件上傳資料。在Spring Boot中,我們可以使用內建的CommonsMultipartResolver類別來實現檔案上傳解析操作。在Spring Boot專案中,只需在Spring設定檔中配置MultipartResolver物件即可,具體程式碼範例如下:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(1000000);
        return multipartResolver;
    }
}

此範例配置了一個CommonsMultipartResolver類別實例,限制了上傳檔案的最大大小為1000000個位元組.注意,我們必須啟用@EnableWebMvc來啟動Spring MVC自適應行為,從而允許CommonsMultipartResolver類別實例的正確工作。

三、Spring Boot中檔案下載

在Spring Boot應用程式開發中,檔案下載也是一種常見的需求。 Spring Boot提供了一個ResponseEntity來代表整個HTTP相應,其中包含相應的狀態碼、頭和正文。我們可以透過設定Content-Disposition來指定下載檔案名稱和類型。

3.1 實作檔案下載

我們可以透過@ResponseBody註解來處理方法傳回的位元組陣列表示的檔案內容,然後使用ResponseEntity傳回整個HTTP響應體。

@GetMapping("/download")
public ResponseEntity<byte[]> download() throws IOException {
    String filePath = "D:/image.jpg";
    File file = new File(filePath);
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Disposition", "attachment;filename=" + file.getName());
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    byte[] bytes = FileUtils.readFileToByteArray(file);
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    return responseEntity;
}

在上述程式碼中,我們使用FileUtils將檔案讀取為位元組數組,將數組設為一個HttpEntity並將其傳回。在傳回的HttpEntity中,我們也指定了檔案的名稱和類型,以便用戶端瀏覽器可以在下載視窗中顯示這些資訊。

3.2 實作多文件下載

在某些情況下,我們需要下載多個文件,可以透過把多個文件打包為一個zip文件,從而實現多文件下載。 Spring Boot中使用java.util.zip套件提供的ZipOutputStream類別很容易實現zip檔案操作,程式碼範例如下:

@GetMapping("/download_multi")
public ResponseEntity<byte[]> downloadMulti() throws IOException {
    String base = "D:/test/";
    File directoryToZip = new File(base);
    List<File> fileList = new ArrayList<>();
    getAllFiles(directoryToZip, fileList);
    byte[] zipBytes = getZipBytes(fileList, base);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.add("Content-Disposition", "attachment; filename="files.zip"");
    headers.setContentLength(zipBytes.length);
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(zipBytes, headers, HttpStatus.OK);
    return responseEntity;
}

private byte[] getZipBytes(List<File> fileList, String basePath) throws IOException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
    for (File file : fileList) {
        String filePath = file.getAbsolutePath().substring(basePath.length());
        ZipEntry zipEntry = new ZipEntry(filePath);
        zipOutputStream.putNextEntry(zipEntry);
        FileInputStream inputStream = new FileInputStream(file);
        IOUtils.copy(inputStream, zipOutputStream);
        inputStream.close();
        zipOutputStream.closeEntry();
    }
    zipOutputStream.close();
    byte[] bytes = outputStream.toByteArray();
    outputStream.close();
    return bytes;
}

private void getAllFiles(File dir, List<File> fileList) {
    File[] files = dir.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            getAllFiles(file, fileList);
        } else {
            fileList.add(file);
        }
    }
}

在上述程式碼中,我們使用ZipOutputStream類別和ByteArrayOutputStream將多個檔案打包成一個zip文件,並透過ResponseEntity傳回整個HTTP回應體,包括zip檔案的位元組陣列、檔案名稱和類型,以便用戶端瀏覽器可以在下載視窗中顯示這些資訊。

四、Spring Boot中檔案儲存

在實際應用中,檔案儲存也是一個重要的環節。我們可以將檔案儲存在本機、FTP、物件儲存等不同位置,這裡我們將以儲存在本機為例,介紹如何透過Spring Boot實現檔案儲存。

4.1 建立儲存目錄

首先,我們需要為儲存服務建立一個目錄,程式碼範例如下:

String fileRoot = "/data/files/";
Path rootPath = Paths.get(fileRoot).normalize().toAbsolutePath();
if (!Files.exists(rootPath)) {
    Files.createDirectories(rootPath);
}

在上述程式碼中,我們建立了一個根目錄/ data/files/用於儲存文件,並檢查目錄是否存在,如果不存在則建立它。

4.2 实现文件存储服务

在Spring Boot中,实现文件存储服务也非常简单,我们可以创建一个类实现存储服务接口,具体代码示例如下:

@Service
public class FileStorageService {

    private Path fileStorageLocation;

    @Autowired
    public FileStorageService(@Value("${file.upload-dir}") String fileRoot) {
        this.fileStorageLocation = Paths.get(fileRoot).normalize().toAbsolutePath();
        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception e) {
            throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", e);
        }
    }

    public String storeFile(MultipartFile file) {
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());
        try {
            if (fileName.contains("..")) {
                throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
            }
            Path targetLocation = this.fileStorageLocation.resolve(fileName);
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
            return fileName;
        } catch (IOException ex) {
            throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

    public Resource loadFileAsResource(String fileName) {
        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if (resource.exists()) {
                return resource;
            } else {
                throw new MyFileNotFoundException("File not found " + fileName);
            }
        } catch (MalformedURLException ex) {
            throw new MyFileNotFoundException("File not found " + fileName, ex);
        }
    }
}

上述代码中,我们创建了一个FileStorageService类,用于实现文件存储服务,包含storeFile()和loadFileAsResource()两个方法,其中:

storeFile()方法用于存储上传的文件,可以获取文件的输入流,将文件存储到指定的存储目录中;

loadFileAsResource()方法用于加载指定文件的Resource对象,通过提供的文件名获取文件的Resource对象。

注意,我们使用@Autowired注解注入了config.properties中对应的配置文件路径,使其自动配置为文件存储的目录。

结语

通过Spring Boot的文件和存储服务,我们可以轻松实现文件操作、上传、下载和存储等操作,简单高效,可以应用于各类企业级Java应用。希望本文对大家对Spring Boot文件和存储服务的理解和实践有所帮助。

以上是如何透過Spring Boot實現檔案與儲存服務的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn