マルチパート
MultipartResolver が有効になると、multipart/form-data による POST リクエストの内容が解析され、通常のリクエストパラメーターとしてアクセスできるようになります。次の例では、1 つの通常のフォームフィールドと 1 つのアップロードされたファイルにアクセスします。
Java
Kotlin
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}@Controller
class FileUploadController {
@PostMapping("/form")
fun handleFormUpload(@RequestParam("name") name: String,
@RequestParam("file") file: MultipartFile): String {
if (!file.isEmpty) {
val bytes = file.bytes
// store the bytes somewhere
return "redirect:uploadSuccess"
}
return "redirect:uploadFailure"
}
} 引数型を List<MultipartFile> として宣言すると、同じパラメーター名の複数のファイルを解決できます。
@RequestParam アノテーションが Map<String, MultipartFile> または MultiValueMap<String, MultipartFile> として宣言され、アノテーションにパラメーター名が指定されていない場合、指定された各パラメーター名のマルチパートファイルがマップに入力されます。
サーブレットのマルチパート解析では、メソッド引数またはコレクション値型として、Spring の MultipartFile の代わりに jakarta.servlet.http.Part を宣言することもできます。 |
コマンドオブジェクトへのデータバインディングの一部としてマルチパートコンテンツを使用することもできます。例: 次の例に示すように、前の例のフォームフィールドとファイルは、フォームオブジェクトのフィールドである可能性があります。
Java
Kotlin
class MyForm {
private String name;
private MultipartFile file;
// ...
}
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(MyForm form, BindingResult errors) {
if (!form.getFile().isEmpty()) {
byte[] bytes = form.getFile().getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}class MyForm(val name: String, val file: MultipartFile, ...)
@Controller
class FileUploadController {
@PostMapping("/form")
fun handleFormUpload(form: MyForm, errors: BindingResult): String {
if (!form.file.isEmpty) {
val bytes = form.file.bytes
// store the bytes somewhere
return "redirect:uploadSuccess"
}
return "redirect:uploadFailure"
}
}RESTful サービスシナリオでは、マルチパートリクエストを非ブラウザークライアントから送信することもできます。次の例は、JSON を含むファイルを示しています。
POST /someUrl
Content-Type: multipart/mixed
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{
"name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.properties"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit
... File Data ...@RequestParam を使用して「メタデータ」部分に String としてアクセスできますが、JSON からデシリアライズすることをお勧めします(@RequestBody と同様)。HttpMessageConverter で変換した後、@RequestPart アノテーションを使用してマルチパートにアクセスします。
Java
Kotlin
@PostMapping("/")
public String handle(@RequestPart("meta-data") MetaData metadata,
@RequestPart("file-data") MultipartFile file) {
// ...
}@PostMapping("/")
fun handle(@RequestPart("meta-data") metadata: MetaData,
@RequestPart("file-data") file: MultipartFile): String {
// ...
}@RequestPart を jakarta.validation.Valid と組み合わせて使用したり、Spring の @Validated アノテーションを使用したりできます。どちらも標準 Bean 検証が適用されます。デフォルトでは、検証エラーにより MethodArgumentNotValidException が発生し、これが 400(BAD_REQUEST)レスポンスに変換されます。または、次の例に示すように、Errors または BindingResult 引数を使用して、コントローラー内で検証エラーをローカルで処理できます。
Java
Kotlin
@PostMapping("/")
public String handle(@Valid @RequestPart("meta-data") MetaData metadata, Errors errors) {
// ...
}@PostMapping("/")
fun handle(@Valid @RequestPart("meta-data") metadata: MetaData, errors: Errors): String {
// ...
} 他のパラメーターに @Constraint アノテーションがあるためにメソッド検証が適用される場合は、代わりに HandlerMethodValidationException が発生します。詳細については、検証のセクションを参照してください。