Home About
Micronaut , Kotlin

HTMLフォームからデータを micronaut にPOSTする

フォームデータがPOSTされたときのサーバ側でのフォームデータ取得の記述方法。

Micronaut

version 確認:

$ mn --version
Micronaut Version: 2.5.7

Step1 プロジェクトの作成とフォーム

それではプロジェクトを作成して、item コントローラをつくるところまで:

$ mn create-app myapp --build=gradle --lang=kotlin
$ cd myapp
$ mn create-controller item

生成された雛形の src/main/kotlin/myapp/ItemController.kt を修正します。

まず / にアクセスしたら Form 付のHTMLを返すようにします。

package myapp

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.HttpStatus

@Controller("/item")
class ItemController {
    //@Get(uri="/", produces=["text/plain"])
    @Get(uri="/", produces=["text/html"])
    fun index(): String {
        return listOf(
            "<html>",
            "<body>",
            "<form action='save' method='post' id='myform'>",
            "<input type=\"text\" name=\"username\" />",
            "<input type=\"submit\" />",
            "</form>",
            "</body>",
            "</html>").joinToString(System.getProperty("line.separator"))
    }
}

処理内容は、Form を含んだHTMLを生成して返しています。 produces を text/plain から text/html に変更しました。

それではサーバ起動:

$ ./gradlew run

http://localhost:8080/item/ にブラウザでアクセスします。

myform

ここまでは、うまくいきました。

Step2 フォームデータの保存処理

次に、フォームを送信したときの保存処理(単なる実験なので実際には保存しませんが)を ItemController に追加します。

    @Post(
        uri="/save/",
        consumes=["application/x-www-form-urlencoded"],
        produces=["text/html"])
    fun save(@Body username: MemoryAttribute): String {
        val usernameValue = username.getValue()

        return listOf(
            "<html>",
            "<body>",
            usernameValue,
            "</body>",
            "</html>").joinToString(System.getProperty("line.separator"))
    }

ポイントは @Body username: MemoryAttribute の部分です。 この username は HTMLフォームの input 要素の name で指定している値( username )と一致させておく必要があります。

このコードで出現したクラスを忘れずにインポートします。

import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Body
import io.netty.handler.codec.http.multipart.MemoryAttribute

Step3 フォームの input 要素が複数あった場合

save を以下のように書き換えます。

    fun save(@Body username: MemoryAttribute, password: MemoryAttribute): String {
        val usernameValue = username.getValue()
        val passwordValue = password.getValue()

例によって、username, password それぞれは フォームのHTML記述にあわせる必要があります。

まとめ

完成したコード ItemController.kt:

package myapp

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.HttpStatus

import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Body
import io.netty.handler.codec.http.multipart.MemoryAttribute

@Controller("/item")
class ItemController {
    @Get(uri="/", produces=["text/html"])
    fun index(): String {
        return listOf(
            "<html>",
            "<body>",
            "<form action='save' method='post' id='myform'>",
            "username: <input type=\"text\" name=\"username\" />",
            "password: <input type=\"text\" name=\"password\" />",
            "<input type=\"submit\" />",
            "</form>",
            "</body>",
            "</html>").joinToString(System.getProperty("line.separator"))
    }

    @Post(
        uri="/save/",
        consumes=["application/x-www-form-urlencoded"],
        produces=["text/html"])
    fun save(@Body username: MemoryAttribute, password: MemoryAttribute): String {
        val usernameValue = username.getValue()
        val passwordValue = password.getValue()

        return listOf(
            "<html>",
            "<body>",
            usernameValue,
            passwordValue,
            "</body>",
            "</html>").joinToString(System.getProperty("line.separator"))
    }
}