前提・実現したいこと
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
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/17 01:31