JAX-RSでファイルダウンロードし、終了したらファイル削除



public class DownloadFile {

  /** 一時領域に作成されたダウンロードファイルのパス */
  public final Path path;

  /** 
   * クライアント側に示されるファイル名。
   * これがクライアント側でセーブされる時のデフォルトのファイル名になる。
   */
  public final String filename;

  /**
   * ダウンロードファイルを作成する
   * @param path 一時領域に作成されたダウンロードファイルのパス
   * @param filename クライアント側がデフォルトで使用するファイル名称
   */
  public DownloadFile(Path path, String filename) {
    this.path = path;
    this.filename = filename;
  }
}
  @Path("/xlsx")
  @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
  @GET
  public Response xlsx(
    @QueryParam("id")
    long id
    ) {

    // idからDownloadFileを取得

    // クライアントに送信する
    return outputDownloadFile(downloadFile);  
  }  
  /**
   * ダウンロードファイルの出力を行う。{@link DownloadFile}に一時ファイルパスとファイル名が含まれている。
   * ダウンロードが終了すると、一時ファイルは消去される。
   * 
   * @param downloadFile {@link DownloadFile}
   * @return 応答
   * @see <a href="https://www.infoscoop.org/blogjp/2012/02/11/jax-rs%E3%81%A7%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89/">
   * JAX-RSでファイルダウンロード</a>
   * @see <a href="https://stackoverflow.com/questions/32064045/how-to-clean-up-temporary-file-after-response-in-jax-rs-rest-service">
   * How to clean up temporary file after response in JAX-RS REST Service?</a>
   */
  Response outputDownloadFile(DownloadFile downloadFile) {

    final StreamingOutput output = o -> {
      Files.copy(downloadFile.path, o);
      Files.deleteIfExists(downloadFile.path);
    };

    return Response.ok(output)
      .header(
        "Content-Disposition",
        "attachment; filename=" + downloadFile.filename
      )
      .build();
  }