LoginSignup
3
2

More than 3 years have passed since last update.

ゼロから始めるSpring Boot その2

Posted at

目標

複数回に分けて実施予定です。

  1. SpringBootとは何かをざっくり知る
  2. 環境構築&Hello World!を表示させる
  3. パラメータやオブジェクトの受け渡しをする ←今回やること
  4. 他の機能にも触れてみる

前置き

前回はHello Worldを表示するために下の2つをやりました。

  • @RestControllerで文字列を表示
  • @Controllerでindex.htmlを表示

プロジェクトは前回作ったものを引き続き使用します。

具体的には以下のようなことをやります。

これを実現するためには、主に2種類の方法があります。
まずは@RequestParamから使っていきましょう。

パラメータを受け渡そう(RequestParam編)

index.html<body>部分を以下のように書き換えます。

index.html
<body>
<form action="/hello" method="get">
名前:
<input type="text" name="username">
<input type="submit" value="送信">
</form>
</body>


各種タグの説明についてはここをクリック。
タグ 要素名 内容
form action リクエストを送るURLを指定。
method 送信方法をGET、POSTから選択して指定。
input type="text" テキストフィールド。
name パラメータに付ける名前。java側で取得する際に使用。
type="submit" パラメータを送信するためのボタン。
value コンテンツ(テキストフィールドやボタンなど)の中身に表示させる文字列を指定。


続けてDemoController.javaに以下のコードを追加します。

DemoController.java
package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class DemoController {

    //前回作成したhelloメソッドと同じです。(メソッド名が被るのでindexに変更)
    @RequestMapping(value="/",method=RequestMethod.GET)
    public ModelAndView index() {
        ModelAndView mav=new ModelAndView();
        mav.setViewName("/index");
        return mav;
    }

    //今回追加するメソッドです。
    @GetMapping("/hello")
    public ModelAndView hello(@RequestParam String username,ModelAndView mav) {
        mav.addObject("username",username);
        mav.setViewName("/hello");
        return mav;
    }
}

ModelAndViewの機能は前回の記事へ!

@RequestParam

引数の先頭に記述。これを付けることにより、リクエストパラメータの値が自動的に変数に格納されます。また、書き方が色々あるのでまとめて紹介します。
例として、送られてくるパラメータの名前は「username」とします。

  • @RequestParam String username
    今回使用している書き方です。変数名(赤字)と、受け取りたいパラメータの名前を同じにする必要があります。変数名と同じパラメータが存在しないとエラーになります。
記述例
@RequestParam String username //OK
@RequestParam String name //NG
  • @RequestParam("username") String username
    一番無難な書き方です。アノテーション側で、受け取りたいパラメータの名前を指定します。存在しない名前を指定してしまうとエラーになります。この時、変数名は任意の名前でOKです。
記述例
@RequestParam("username") String username //OK
@RequestParam("username") String name //OK
@RequestParam("name") String username //NG
  • @RequestParam(value="username",required=false) String username
    あまり出てきません。valueでパラメータの名前を、requiredでパラメータの存在を必須条件にするかどうかが選べます。デフォルトはtrueです。
    falseにすると指定したパラメータが存在しなくてもエラーになりません(当然パラメータの受け渡しは出来ませんが・・・)。これも変数名は任意の名前でOKです。
記述例
@RequestParam(value="username",required=false) String username //OK
@RequestParam(value="name",required=false) String name //OK でも受け渡しは出来ない
@RequestParam(value="name",required=true) String name //NG

続いてパラメータを受け取るHTMLファイルを作成します。
index.htmlと同じフォルダにhello.htmlという名前でHTMLファイルを作成し、中身を以下のように書き換えてください。

hello.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<span th:text="${username}"></span>さん、Hello World!
</body>
</html>
  • <html xmlns:th="http://www.thymeleaf.org">
    この記述によってThymeleafの機能をthから始まるタグ名で呼び出せるようになります。
    Thymeleafってなんだ?については前回の記事公式ドキュメントへ!
  • th:text="${パラメータ名}"
    ModelAndViewに格納されたパラメータを取得してコンテンツに表示します。<div><td><p>タグなどの時に使用します。
  • th:value="${パラメータ名}"
    th:textと同様。こちらは<input type="text">などで使用します。

他のタグについては登場時に都度解説していきます。


それではhttp://localhost:8080にアクセスしてみましょう。

適当に名前を入力して「送信」ボタンをクリック。

入力した名前が次のページで表示できました!

上記が@RequestParamによるパラメータの受け渡しです。
画像でまとめると以下のようなイメージになります。
flow_param.png

パラメータを受け渡そう(PathVariable編)

続いてはGET方法でのみ可能なパラメータの受け渡し方法です。
この方法では、URLに含まれている文字列をそのまま取得することができます。
(例えばhttp://localhost:8080/hello/xxxにアクセスしたとき、xxxをパラメータとして取得できます)

DemoController.javahelloメソッドを書き換えます。

DemoController.java
@GetMapping("/hello/{username}")
public ModelAndView hello(@PathVariable String username,ModelAndView mav) {
    mav.addObject("username",username);
    mav.setViewName("/hello");
    return mav;
}

@GetMapping

これ自体は前回やっているのですが、問題は引数の方です。
URLから取得したい部分を{}で囲み、後述する@PathVariableで呼び出す用の名前を中に入れます。

@PathVariable

引数の先頭に記述。これも書き方が複数ありますが、@RequestParamと同じのため割愛します。

また、パラメータは複数取得可能です。
たとえば「http://localhost:8080/hello/hatopo/24にアクセスしたとき、hatopo24を取得したいなあ」といった場合は以下のように記述します。

記述例
@GetMapping("/hello/{username}/{age}")
public ModelAndView hello(@PathVariable String username,@PathVariable int age,ModelAndView mav) {
    // 中身は省略
    return mav;
}

それではhttp://localhost:8080/hello/xxxにアクセスしてみましょう。
(xxxは任意の文字列を入れてください)

/hello以降のパラメータを表示できました!


パラメータの受け渡し感が無いな・・・と思う人へ
完全に蛇足ではありますが、テキストフィールドの値をURLにくっ付けてページ遷移させるjavascriptを記述することでパラメータの受け渡しができます。
index.html<body>内を以下のように書き換えます。
index.html
<body>
名前:<input type="text" id="name">
<input type="submit" value="送信" onclick="send()">
<script>
function send(){
    var name = document.getElementById("name").value;
    if(name == "")name = "default_name";
    location.href = "http://localhost:8080/hello/" + name;
}
</script>
</body>

http://localhost:8080/にアクセスして名前を入れて「送信」ボタンを押すと入力値が表示できます!


以上がパラメータの受け渡しになります。続けてオブジェクトの受け渡しもやりましょう。

オブジェクトの受け渡し

オブジェクトについて知らない人は、とりあえず今はパラメータの入った箱(クラス)といった理解で大丈夫です。

まず、DemoControllerと同じフォルダにUserという名前でクラスを作成し、以下のコードを追加してください。

User.java
package com.example.demo;

public class User {
    private String name;
    private int age;
}

続けてgettersetterと呼ばれる、javaがパラメータの取得/設定をするために必要なメソッドを追加します。
手動で書いてもOKですが、自動で追加する場合はUserクラス内の適当な場所にカーソルを置いてソース>>getterおよびsetterの生成の順にクリック。

すべて選択>>生成の順にクリック。

コード全体が以下のようになればOKです。

User.java
package com.example.demo;

public class User {
    private String name;
    private int age;
    // ↓自動生成によって追加されるコード
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    // ↑自動生成によって追加されるコード
}

※Lombokというプラグインを利用するとこのコードの記述が不要になりますが、この記事では扱いません。

続けてindex.htmlを以下のように書き換えます。

index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/hello" method="get" th:object="${user}">
名前:<input type="text" name="name"><br>
年齢:<input type="text" name="age"><br>
<input type="submit" value="送信">
</form>
</body>
</html>
  • th:object="${オブジェクト名}"
    これを記述したタグ内にあるパラメータをまとめて1つのオブジェクト名で参照できるようにします。この例だと、nameageuserという名前の箱に入れます。

DemoController.javahelloメソッドも書き換えましょう。

DemoController.java
@GetMapping("/hello")
public ModelAndView hello(@ModelAttribute User user,ModelAndView mav) {
    mav.addObject("user",user);
    mav.setViewName("/hello");
    return mav;
}

@ModelAttribute

引数の先頭に記述。フォームから送られてきたオブジェクトを変数に格納します。
このとき、Springが裏で下のようなことをしてくれます。

内部の処理
User user = new User();
user.setName(name);
user.setAge(age);

そのため、Userクラスにnameというフィールド変数が定義されていなかったり、setAgeメソッドが定義されていなかったりすると正しく動きません。

また、このアノテーションはメソッドに書くこともできますが、使い道がだいぶ異なるためこの記事では割愛します...


最後にhello.htmlを以下のように書き換えましょう。

hello.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:object="${user}">
<span th:text="*{name}"></span>さんは
<span th:text="*{age}"></span>歳です!
</div>
</body>
</html>
  • th:text="*{パラメータ名}"
    th:text="${オブジェクト名.パラメータ名}"の省略形です。
    th:object={}を記述したタグ内においては上記のように省略して書くことができます。

それではhttp://localhost:8080にアクセスしましょう。

適当に名前と年齢を入力して「送信」ボタンを押すと・・・

名前と年齢を表示できました!

おさらい

  • @RequestParamでパラメータの受け渡し
  • @PathVariableでURLパラメータの取得
  • @ModelAttributeでオブジェクトの受け渡し

今回はここまでです。お疲れ様でした。
次回からはより本格的な機能について触れていきます。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2