質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

4263閲覧

Spring Bootでbindingに失敗する

KentaNakamoto

総合スコア23

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2021/08/10 01:56

前提・実現したいこと

Spring Boot(kotlin)で、ファイルをアップロードするアプリを作成中です。
spring initializrでひな形を作成した後、Qiitaのこのサイトをもとにプログラムを作成したところ、ページ自体は無事に開けたのですが、「送信する」ボタンを押すとエラーが生じました。

発生している問題・エラーメッセージ

@GetMapping("/")ではエラーが生じませんでしたが、@PostMapping("/upload")で以下のようなエラーが生じました。bindingでこけているようです。

org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputFileFieldTagProcessor' (template: "index" - line 11, col 12) at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE] <以下略> Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'updateForm' available as request attribute at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153) ~[spring-webmvc-5.3.9.jar:5.3.9] <以下略> 2021-08-10 10:13:47.582 ERROR 19072 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputFileFieldTagProcessor' (template: "index" - line 11, col 12)] with root cause java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'updateForm' available as request attribute at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903) ~[spring-webmvc-5.3.9.jar:5.3.9] <以下略>

該当のソースコード

kotlin

1 2**HomeController** 3 4import org.springframework.stereotype.Controller 5import org.springframework.ui.Model 6import org.springframework.web.bind.annotation.GetMapping 7import org.springframework.web.bind.annotation.PostMapping 8import org.springframework.web.multipart.MultipartFile 9import java.io.IOException 10import java.nio.file.Files 11import java.nio.file.Path 12import java.nio.file.Paths 13import java.nio.file.StandardOpenOption 14import java.time.LocalDateTime 15import java.time.format.DateTimeFormatter 16 17 18@Controller 19class FileUploadController { 20 private fun getExtension(filename: String?): String { 21 val dot = filename!!.lastIndexOf(".") 22 return if (dot > 0) { 23 filename.substring(dot).toLowerCase() 24 } else "" 25 } 26 27 private fun getUploadFileName(fileName: String?): String { 28 return (fileName + "_" + 29 DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS") 30 .format(LocalDateTime.now()) 31 + getExtension(fileName)) 32 } 33 34 private fun createDirectory() { 35 val path: Path = Paths.get("C:/upload/files") 36 if (!Files.exists(path)) { 37 try { 38 Files.createDirectory(path) 39 } catch (e: Exception) { 40 //エラー処理は省略 41 } 42 } 43 } 44 45 private fun savefile(file: MultipartFile) { 46 val filename = getUploadFileName(file.originalFilename) 47 val uploadfile: Path = Paths.get("C:/upload/files/$filename") 48 try { 49 Files.newOutputStream(uploadfile, StandardOpenOption.CREATE).use { os -> 50 val bytes = file.bytes 51 os.write(bytes) 52 } 53 } catch (e: IOException) { 54 //エラー処理は省略 55 } 56 } 57 58 private fun savefiles(multipartFiles: List<MultipartFile>) { 59 createDirectory() 60 for (file in multipartFiles) { 61 savefile(file) 62 } 63 } 64 65 66 @GetMapping("/") 67 fun uploadview(model: Model): String { 68 model.addAttribute("updateForm", UploadForm()) 69 return "index" 70 } 71 72 73 @PostMapping("/upload") 74 fun upload(model: Model?, form: UploadForm): String { 75 76 if (form.file == null || form.file.isEmpty()) { 77 //エラー処理は省略 78 return "index" 79 } 80 81 savefiles(form.file) 82 return "redirect:/" 83 } 84}

kotlin

1 2**UploadForm** 3 4import org.springframework.web.multipart.MultipartFile 5 6class UploadForm { 7 val file: List<MultipartFile>? = null 8}

html

1 2**index.html** 3 4<!DOCTYPE HTML> 5<html xmlns:th="http://www.thymeleaf.org"> 6<head> 7 <title>top page</title> 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 9</head> 10<body> 11<h2>ファイルアップロード</h2> 12<form method="post" th:action="@{/upload}" th:object="${updateForm}" > 13 14 <input th:field="*{file}" type="file" multiple/> 15 16 <input type="submit" value="送信する"/> 17 18</form> 19</body> 20</html>
**Gradle** import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "2.6.0-M1" id("io.spring.dependency-management") version "1.0.11.RELEASE" kotlin("jvm") version "1.5.21" kotlin("plugin.spring") version "1.5.21" } group = "com.example" version = "0.0.1-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() maven { url = uri("https://repo.spring.io/milestone") } } dependencies { implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("org.springframework.boot:spring-boot-starter-web") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") testImplementation("org.springframework.boot:spring-boot-starter-test") implementation("org.springframework.boot:spring-boot-starter-validation") //implementation("org.springframework.boot:spring-boot-starter-jdbc") //implementation ("org.springframework.boot:spring-boot-starter-data-jpa") } tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "11" } } tasks.withType<Test> { useJUnitPlatform() }

試したこと

ファイルアップロード時のbindingでこけているようでしたので、<input th:field="*{file}" type="file" multiple/>から<input th:field="*{file}" type="text"/>に変えてみましたが、同じエラーがでました。以上より、@PostMappingのコードの書き方がおかしいのでは?と思っていますが、どのようにおかしいのかわかりません。

補足情報(FW/ツールのバージョンなど)

Spring Boot 2.6.0-M1
Java SDK 14.0.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

UploadFormでプロパティfileをvalで宣言しているためだと思います。
valはイミュータブル(読み取り専用)のため、FileUploadControllerのuploadviewでインスタンス生成時にnullが代入された後には変更できません。
varで宣言することで、ミュータブル(可変)として宣言できます。

投稿2021/08/14 13:57

eslint

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KentaNakamoto

2021/08/17 01:31

ありがとうございます。解決しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問