今回も引き続き、ファイルアップロード・ダウンロード機能の実装について述べる。ここでは、具体的なサンプルプログラムのソースコードを共有する。
前提条件
下記記事を参照のこと。
Spring BootのWEB画面上でファイルアップロード・ダウンロード機能を実装してみた(完成イメージと前提条件)前回は、Spring Bootのmybatisを利用して、「BLOB」「CLOB」を含むテーブルへのデータ追加・データ参照を行った。今回...
作成したサンプルプログラムの内容
なお、上図の赤枠は、下記記事に記載したソースコードと比較し、変更になったソースコードを示す。赤枠のソースコードについては今後記載する。
Spring Bootで、OracleのテーブルにBLOB,CLOBのカラムを含む場合のOracle接続を実装してみたOracleのデータ型に、大量のデータやバイナリデータを格納できる「BLOB」「CLOB」がある。「BLOB」にはバイナリデータ、「CL...
ファイルデータ(file_data)テーブルにアクセスするMapperクラスは以下の通り。今回必要なfindAllメソッド・getMaxIdメソッドを追加している。
package com.example.demo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface FileDataMapper {
/**
* ファイルデータテーブル(file_data)から全件取得する
* @return ファイルデータテーブル(file_data)のデータリスト
*/
@Select("SELECT id, file_path as filePath, file_obj as fileObj "
+ " FROM file_data ORDER BY id asc")
List<FileData> findAll();
/**
* 指定したIDをもつファイルデータテーブル(file_data)のデータを取得する
* @param id ID
* @return ファイルデータテーブル(file_data)の指定したIDのデータ
*/
@Select("SELECT id, file_path as filePath, file_obj as fileObj "
+ " FROM file_data WHERE id = #{id}")
FileData findById(Long id);
/**
* ファイルデータテーブル(file_data)の最大値IDを取得する
* @return ファイルデータテーブル(file_data)の最大値ID
*/
@Select("SELECT NVL(max(id), 0) as maxId FROM file_data")
long getMaxId();
/**
* 指定したファイルデータテーブル(file_data)のデータを追加する
* @param fileData ファイルデータテーブル(file_data)
*/
@Insert("INSERT INTO file_data ( id, file_path, file_obj ) "
+ " VALUES ( #{id}, #{filePath}, #{fileObj} )")
void insert(FileData fileData);
}
「CODE×CODE」は、需要の高い技術(AWS, Python等)を習得できるプログラミングスクールスクールだった近年、さまざまな会社でクラウド(特にIaaSやPaaSのパブリッククラウド)の需要が非常に高まっていて、クラウドサービスによるシステム開...
また、ファイルデータ(file_data)テーブルにアクセスするMapperクラスを利用するコントローラクラスは以下の通り。ここではファイルアップロード・ファイルダウンロード処理も記載している。
ファイルアップロード処理(addメソッド)内では引数のMultipartFileオブジェクトからファイルオブジェクトを取得後、ファイルデータテーブルへのデータ追加を行っている。また、ファイルダウンロード処理(downloadメソッド)内では指定したIDのデータ取得後、HttpServletResponseクラスのwriteメソッドでダウンロード出力を行っている。
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
@Controller
public class DemoController {
/**
* ファイルデータテーブル(file_data)へアクセスするMapper
*/
@Autowired
private FileDataMapper fileDataMapper;
/**
* ファイルデータ一覧表示処理
* @param model Modelオブジェクト
* @return 一覧画面
*/
@RequestMapping("/")
public String index(Model model){
//ファイルデータテーブル(file_data)を全件取得
List<FileData> list = fileDataMapper.findAll();
model.addAttribute("fileDataList", list);
//一覧画面へ移動
return "list";
}
/**
* ファイルデータ登録画面への遷移処理
* @return ファイルデータ登録画面
*/
@PostMapping("/to_add")
public String to_add(){
return "add";
}
/**
* ファイルデータ登録処理
* @param uploadFile アップロードファイル
* @return ファイルデータ一覧表示処理
*/
@PostMapping("/add")
@Transactional(readOnly = false)
public String add(@RequestParam("upload_file") MultipartFile uploadFile){
//最大値IDを取得
long maxId = fileDataMapper.getMaxId();
//追加するデータを作成
FileData fileData = new FileData();
fileData.setId(maxId + 1);
fileData.setFilePath(uploadFile.getOriginalFilename());
try{
fileData.setFileObj(uploadFile.getInputStream());
}catch(Exception e){
System.err.println(e);
}
//1件追加
fileDataMapper.insert(fileData);
//一覧画面へ遷移
return "redirect:/to_index";
}
/**
* 追加完了後に一覧画面に戻る
* @param model Modelオブジェクト
* @return 一覧画面
*/
@GetMapping("/to_index")
public String toIndex(Model model){
return index(model);
}
/**
* ファイルダウンロード処理
* @param id ID
* @param response HttpServletResponse
* @return 画面遷移先(nullを返す)
*/
@RequestMapping("/download")
public String download(@RequestParam("id") String id
, HttpServletResponse response){
//ダウンロード対象のファイルデータを取得
FileData data = fileDataMapper.findById(Long.parseLong(id));
//ファイルダウンロードの設定を実施
//ファイルの種類は指定しない
response.setContentType("application/octet-stream");
response.setHeader("Cache-Control", "private");
response.setHeader("Pragma", "");
response.setHeader("Content-Disposition"
,"attachment;filename=\"" + getFileName(data.getFilePath()) + "\"");
//ダウンロードファイルへ出力
try(OutputStream out = response.getOutputStream();
InputStream in = data.getFileObj()){
byte[] buff = new byte[1024];
int len = 0;
while ((len = in.read(buff, 0, buff.length)) != -1) {
out.write(buff, 0, len);
}
out.flush();
}catch(Exception e){
System.err.println(e);
}
//画面遷移先はnullを指定
return null;
}
/**
* ファイルパスからファイル名を取得する
* @param filePath ファイルパス
* @return ファイル名
*/
private String getFileName(String filePath){
String fileName = "";
if(filePath != null && !"".equals(filePath)){
try{
//ファイル名をUTF-8でエンコードして指定
fileName = URLEncoder.encode(new File(filePath).getName(), "UTF-8");
}catch(Exception e){
System.err.println(e);
return "";
}
}
return fileName;
}
}サラリーマン型フリーランスSEという働き方でお金の不安を解消しよう先日、「サラリーマン型フリーランスSE」という働き方を紹介するYouTube動画を視聴しましたので、その内容をご紹介します。 「サ...
さらに、一覧画面・入力画面のソースコード内容は以下の通り。ファイルアップロードを行うファイルの選択は、inputタグのtype=”file”で指定していて、nameタグの内容をコントローラクラスの引数のMultipartFileオブジェクトとして渡している。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>一覧画面</title>
</head>
<body>
ファイルデータテーブル(file_data)の全データ<br/><br/>
<table border="1" cellpadding="5">
<tr>
<th>ID</th>
<th>ファイルパス</th>
<th></th>
</tr>
<tr th:each="obj : ${fileDataList}">
<td th:text="${obj.id}"></td>
<td th:text="${obj.filePath}"></td>
<td>
<!-- ダウンロードボタンを表示 -->
<form action="#" method="get"
th:action="@{/download(id=${'__${obj.id}__'})}"
th:method="download" >
<input type="hidden" name="_method" value="download" />
<input type="submit" value="ダウンロード" />
</form>
</td>
</tr>
</table>
<br/><br/>
<form method="post" th:action="@{/to_add}">
<input type="submit" value="データ追加" /><br/><br/>
<input type="button" value="閉じる" onclick="window.close();" />
</form>
</body>
</html><!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>入力画面</title>
</head>
<body>
<p>入力ファイルを指定し、「登録」ボタンを押下してください。</p><br/>
<form method="post" enctype="multipart/form-data" th:action="@{/add}">
ファイル : <input type="file" name="upload_file" /><br/><br/>
<input type="submit" value="送信" />
<input type="button" value="戻る" onclick="history.back();" />
</form>
</body>
</html>その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-upload-download-2/demo
要点まとめ
- ファイルアップロード処理では、HTMLファイルでinputタグのtype=”file”を指定し、nameタグの内容をコントローラクラスの引数のMultipartFileオブジェクトとして渡すことで、ファイルオブジェクトを連携できる。
- ファイルダウンロード処理では、HttpServletResponseオブジェクトのwriteメソッドで、ダウンロード出力処理を行えばよい。






