たなかのJava日記

どんなことをやったか(学んだか)、どこで詰まったか(わからなかったか)、どこで工夫したかの記録です。

【Spring Boot】@Controllerでコントローラを作成する

まずJavaによるWebアプリケーションの仕組みについての復習です。

Webアプリケーションは3つのパーツに分けて考えることができます。
その3つとは「モデル」、「ビュー」、「コントローラ」です。
それぞれの役割は以下になります。


1、「モデル」
 ⇒アプリケーションで使用するデータを保持する部分

2、「ビュー」
 ⇒ユーザーによって利用されるユーザーインターフェースの部分

3、「コントローラ」
 ⇒ユーザーインターフェース(Webページ)から送られてくるリクエストを処理する部分


この3つを組み合わせるような構成や仕組みを「MVCモデル」と呼ばれることがあります。MVCは3つの頭文字を取ったものです。


これまで、タスク管理アプリケーションの「モデル」、「コントローラ」の部分は作りましたが、UIの部分を担う「ビュー」については、単にテキストを表示するだけでした。
しかし、これではWebアプリとは到底呼べません。
ここからはタスク管理アプリケーションを「ビュー」を持つように変更していきます。


WebアプリケーションにおけるUIとは、
ご存知かとは思いますが、HTMLを使って記述されたWebページとなります。
これまではWebブラウザへのレスポンスとして文字列をそのまま返していましたが、UIとして成立させるために見た目を整えてHTMLとして返す必要があります。
また、リクエストのパラメータについてもアドレスバーにURLの一部として打ち込むのではなく、HTMLのフォームから入力できるようにしなくてはなりません。


これから行うことをまとめると以下になります。

1、Webブラウザへのレスポンスとして文字列をそのまま返していたのを変更
 ⇒WebアプリケーションのUIとして成立させるために見た目を整えてHTMLとして返す

2、リクエストのパラメータはアドレスバーにURLの一部として打ち込んでいたのを変更
 ⇒WebアプリケーションのUIとして成立させるために、HTMLのフォームから入力できるようにする


まず、1についてです。
HTTPレスポンスとして、HTMLを返したい場合は、Spring Webに用意されている@Controtllerを使用します。
となると、これまで使用していた@RestControllerは、HTTPレスポンスとして文字列を返すために使用していたということになります。

早速、@Controllerを使用したコントローラを作成するために、新しくHomeControllerという名前のクラスを作成します。

package jp.gihyo.projava.talklist;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalDateTime;

@Controller
public class HomeController {
    @RequestMapping(value="/hello")
    @ResponseBody()
    String hello() {
        return """
                <html>
                    <head><title>Hello<title></head>
                    <body>
                        <h1>Hello</h1>
                        It works!<br>
                        現在時刻は%sです。
                    </body>
                </html>
                """.formatted(LocalDateTime.now());
    }
}


@RestControllerと同様、helloメソッドの@RequestMappingは同じです。
"/hello"としてパスに対するエンドポイント指定し、文字列を返しています。
しかし、返す文字列の内容がHTMLになっている点が大きく違います。

エンドポイントとは簡単に言うと、「Webブラウザ(クライアント)との窓口となるメソッド」のことです。

@Controllerでコントローラを作成する場合、
レスポンスとして返す際に、サーバー側のプログラム内でWebコンテンツを生成して返すことになります。

その他の違う点としては、@Controllerのhelloメソッドには@ResponseBodyというアノテーションが付いています。
このアノテーションを付けることで、Stringのオブジェクト自体がレスポンス本体として扱われるようになります。
別の言い方をすると、メソッドの戻り値を Web レスポンスの本文にバインドする(埋め込む)必要があることを示すアノテーションになります。


なぜこのアノテーションが必要かというと、
@Controllerを使った場合にはデフォルトの挙動として、
各エンドポイントメソッドは戻り値として「ビューを表すオブジェクトの名称」を返すことになっているからです。
「ビューを表すオブジェクトの名称」とは、端的に言えばレスポンス本体のHTML文書を生成してくれるオブジェクトのことです。
helloメソッドの場合、自分自身でHTML文書をStringオブジェクトととして生成し、戻り値として返しています。
なので、このまま@ResponseBody無しで返しても厳密にはHTMLではないのでエラーになります。
@Controllerを使った場合の戻り値(レスポンス)は、HTMLでないといけないということです。
@ResponseBodyを付けることで、Stringのオブジェクト自体がレスポンス本体(HTML)として扱われるようになります。


理解が出来たら、プロジェクトを再実行します。
問題なく起動が出来たら、Webブラウザから以下のアドレスを入力します。

 

http://localhost:8888/hello
※8888の箇所は自分で指定したポート番号にする


ブラウザに以下のように表示されたら成功です。


Hello
It works!
現在時刻は2022-05-06T18:22:34.879833600です。