Springbootファイルのダウンロード


Springbootは、ClassPathResource、FileSystemResource、UrlResource、ByteArrayResource、
サーブレットContextResourceとInputStreamResource.
  • ClassPathResourceを使用して、クラスパスの下にあるリソースファイルを取得できます.リソースファイルがあるとしますtxtはクラスパスの下で、対応するリソースファイルのクラスパスの下でのパスpathを指定することで取得できます.new ClassPathResource(「test.txt」)です.
  • FileSystemResourceは、ファイルシステム内のリソースを取得するために使用できます.リソースファイルのファイルパスに対応してFileSystemResourceを構築できます.FileSystemResourceは、対応するリソースファイルに内容を書くこともできます.もちろん、現在のリソースファイルが書けることを前提としていますが、isWritable()メソッドで判断できます.FileSystemResourceは、対応するリソースファイルの出力ストリームを公開しており、getOutputStream()メソッドで取得できます.
  • UrlResourceは、URLに対応するリソースを表すために使用することができ、URLを簡単にカプセル化します.URLアドレスを指定することで、UrlResourceを構築できます.
  • ByteArrayResourceは、バイト配列にカプセル化されたリソースであり、その構築にはバイト配列が必要である.
  • サーブレットContextResourceは、サーブレットContext環境下のリソースにアクセスするためにサーブレットContextにカプセル化されたリソースです.サーブレットContextResourceは、サーブレットContextのgetResource()メソッドとgetResourceAsStream()メソッドによってリソースを取得するサーブレットContextの参照を持っています.
  • InputStreamResourceは、入力ストリームにカプセル化されたリソースであり、その構築には入力ストリームが必要である.

  • Resourceインタフェースでは、主に次の方法が定義されています.
  • exists():対応するリソースが本当に存在するかどうかを判断するために使用されます.
  • isReadable():対応するリソースのコンテンツが読み取り可能かどうかを判断するために使用されます.結果がtrueの場合、そのコンテンツは必ずしも本当に読めるとは限らないが、falseを返すと、そのコンテンツは必ず読めないことに注意してください.
  • isOpen():現在のリソースが開いている入力ストリームを表しているかどうかを判断するために使用され、結果がtrueの場合、現在のリソースの入力ストリームは複数回読み取り不可であり、読み取り後にメモリの漏洩を防ぐために閉じる必要があることを示します.この方法は主にInputStreamResourceに適用され,実装クラスではその戻り結果のみがtrueであり,その他はfalseである.
  • getURL():現在のリソースに対応するURLを返します.現在のリソースがURLに解析できない場合は、例外が放出されます.ByteArrayResourceではURLとして解析できません.
  • getFile():現在のリソースに対応するFileを返します.現在のリソースが絶対パスで1つのFileに解析できない場合は、例外が放出されます.ByteArrayResourceではファイルとして解析できません.
  • getInputStream():現在のリソースが表す入力ストリームを取得します.InputStreamResource以外の他のResourceインプリメンテーションクラスは、getInputStream()メソッドを呼び出すたびに、新しいInputStreamを返します.
  • およびJavaのFileのようなインタフェース、例えばgetName、getContenLengthなど.

  • ローカルファイルシステムの指定したパスの下にあるファイルを取得する必要がある場合は、いくつかの方法があります.
  • ResponseEntityにより
  • を実現
  • HttpServeretResponseのOutputStreamを書くことで
  • を実現する.
    1つ目の方法は、ResponseEntityをカプセル化することによって、bodyにファイルストリームを書き込むことです.ここで注意したいのは、ファイルのフォーマットは特定のファイルのタイプに応じて設定する必要があり、一般的にはアプリケーション/octet-streamとデフォルトで設定されています.ファイルヘッダにキャッシュとファイルの名前を設定します.ファイルの名前が書き込まれると、ファイルがランダムに名前を生成し、認識できない問題を回避できます.
    @RequestMapping(value = "/media", method = RequestMethod.GET)
        public ResponseEntity downloadFile( Long id)
                throws IOException {
            String filePath = "E:/" + id + ".rmvb";
            FileSystemResource file = new FileSystemResource(filePath);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getFilename()));
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
    
            return ResponseEntity
                    .ok()
                    .headers(headers)
                    .contentLength(file.contentLength())
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(new InputStreamResource(file.getInputStream()));
        }

    2つ目の方法はJavaのFileファイルリソースを採用し、responseの出力ストリームを書くことでファイルを戻すことです.
    @RequestMapping(value="/media/", method=RequestMethod.GET)
        public void getDownload(Long id, HttpServletRequest request, HttpServletResponse response) {
    
            // Get your file stream from wherever.
            String fullPath = "E:/" + id +".rmvb";
            File downloadFile = new File(fullPath);
    
            ServletContext context = request.getServletContext();
    
            // get MIME type of the file
            String mimeType = context.getMimeType(fullPath);
            if (mimeType == null) {
                // set to binary type if MIME mapping not found
                mimeType = "application/octet-stream";
                System.out.println("context getMimeType is null");
            }
            System.out.println("MIME type: " + mimeType);
    
            // set content attributes for the response
            response.setContentType(mimeType);
            response.setContentLength((int) downloadFile.length());
    
            // set headers for the response
            String headerKey = "Content-Disposition";
            String headerValue = String.format("attachment; filename=\"%s\"",
                    downloadFile.getName());
            response.setHeader(headerKey, headerValue);
    
            // Copy the stream to the response's output stream.
            try {
                InputStream myStream = new FileInputStream(fullPath);
                IOUtils.copy(myStream, response.getOutputStream());
                response.flushBuffer();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }