little star's memory

競プロ、なぞなぞ

Kotlinでサーバーサイドのお勉強 第3回 POST

今回も引き続きMicronautでWeb開発の勉強をする。

前回はGETを使ったので、今回はPOSTを試してみる。

まず完成形は次のような感じ。

地名と天気を入力してボタンを押すと、POSTでデータがやり取りされる。今回はデータベースを使うわけではないので、実際に追加されるわけではない。

さて実装していく。まずはindex.htmlを改修。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>Home</title>
</head>
<body>
<ul>
    <li th:each="data : ${dataList}">
        <span th:text="${data.city}"></span><span th:text="${data.weather}"></span>
    </li>
</ul>
<form action="/add" method="post">
    <label for="city">地名:</label>
    <input id="city" name="city">
    <label for="weather">天気:</label>
    <input id="weather" name="weather">
    <button type="submit">追加</button>
</form>
</body>
</html>

th:eachでリストの中身を列挙する。いいよねこれ。

下の方では追加機能っぽいものを作っている。ボタンをクリックすると/addにPOSTが飛ぶ。cityとweatherの2つ入力欄がある。idとnameの違い、覚えてない。

次はadd.htmlを作る。ボタンをクリックした先。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>add</title>
</head>
<body>
<p>
    <span th:text="${city}"></span><span th:text="${weather}"></span>です。
</p>
<p>
    <a th:href="@{/hello}">戻る</a>
</p>
</body>
</html>

th:hrefと@でいい感じのリンクが生成される。面白い。

次はKotlinを書いていく。

package com.example

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.HttpResponse
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Post
import io.micronaut.views.View

data class WeatherData(val city: String, val weather: String)

@Controller
class ViewController {
    @Get("/hello")
    @View("index")
    fun index(): HttpResponse<*>? {
        return HttpResponse.ok(mapOf("dataList" to listOf(
            WeatherData(city = "東京", weather = "晴れ"),
            WeatherData(city = "大阪", weather = "雨"),
        )))
    }

    @Post(value = "/add", consumes = [MediaType.APPLICATION_FORM_URLENCODED])
    @View("add")
    fun add(@Body("city") city: String, @Body("weather") weather: String): HttpResponse<*>? {
        return HttpResponse.ok(mapOf("city" to city, "weather" to weather))
    }
}

data classは簡潔に書けて良いとされている。Javaだとこうはいかないらしい。

@Postのアノテーションをつけたところを見ていく。consumesはよくわからなかった。多分こういう形でデータを受け取るよ、ということを表している (違うかも)。似たようなオプションにproducesもあるけれど、今回はテンプレートを使うので書かない。

やり取りする内容はリクエストボディというらしい。@Bodyアノテーションをつける。cityとweatherの2つを受け取るので、それぞれに代入する (バインディングというらしい)。

実行

実行してみる。

入力してボタンをクリックすると…。

ちゃんとデータを受け渡すことができた。

戻るを押してもデータは追加されていない。

まとめ

MicronautでPOSTを使ってみた。

大したことしてないように見えるかもしれないが、これでも色々調べたり試行錯誤をして完成させている。初心者なので…。

次回はデータベースをやってみたい。前回Spring Bootを触っていたときはデータベースをやっていなかった気がするので、できるかどうかはわからない。

参考文献

qiita.com