spring.svg

【Spring Boot】ファイル送受信

SpringBoot

ファイルの送信

ローカルファイルを読み込んでクライアントに送信することを考えます。

ファイルを送信する場合は、以下のレスポンスヘッダーを設定し、レスポンスボディにファイルの内容を書き込みます。

ヘッダー設定値
Content-Typeapplication/octet-stream
Content-Dispositionattachment; filename=ファイル名

Spring Boot でレスポンスの設定を変更するには、Controller のメソッド引数にHttpServletResponseを指定します。

@RestController
public class SampleController {
  @GetMapping("download")
  public void download(HttpServletResponse response) {
    //ローカルファイルの読み込み
    try (InputStream is = new FileInputStream("ファイルのパス");
            OutputStream os = response.getOutputStream();) {
      //レスポンスヘッダーの設定
      response.setHeader("Content-Disposition", "attachment; filename=ファイル名");
      response.setContentType("application/octet-stream");
      //レスポンスボディへの書き込み
      IOUtils.copy(is, os);
      os.flush();
    } catch (IOException e) {
      throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}

ファイルの受信

Content-Type: multipart/form-dataで送信されたファイルを受信することを考えます。

Spring Boot では、multipart/form-dataで送信されたそれぞれの情報を@RequestPart(名前)で取得することができます。

以下はファイルと JSON データをそれぞれfileparamsという名前で送られる場合の例です。

@RestController
public class SampleController {
  @PostMapping("upload")
  public void upload(@RequestPart("file") MultipartFile file, @RequestPart("params") @Validated SampleDataParams params) {
    Path savePath = Paths.get("保存先のパス");
    try (OutputStream os = Files.newOutputStream(savePath, StandardOpenOption.CREATE)) {
      os.write(file.getBytes());
    } catch (IOException e) {
      throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}

ファイルはMultipartFileで受け取ることができます。これをローカルに保存する方法は上の例の通りです。

JSON データは DTO を指定することで対応するインスタンスが生成されます。このとき@RequestBodyの指定は不要です。 また@Validatedを付与することでバリデーションを実行することも可能です。

受信サイズの制限設定

Spring Boot では、multipart/form-dataで受信できるリクエストのサイズと、1 ファイルあたりのサイズがそれぞれ10MB1MBと決められています。

この設定はapplication.ymlapplication.properties)で変更することができます。

application.yml
spring:
  servlet:
    multipart:
      max-request-size: 10MB
      max-file-size: 1MB