コントローラーの作成 - @Controller

コントローラーには、@Controller、および @RequestMapping を使用します。作成済みのビューをレスポンスする、demo というエンドポイントを、以下を参考に作成します。

// src/main/java/io/github/yo1000/sss/controller/page/MemoController.java
package io.github.yo1000.sss.controller.page;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("memo")
public class MemoController {
    @RequestMapping("")
    public String get(Model model) {
        List<Map<String, Object>> items = new ArrayList<>();
        Map<String, Object> item = new HashMap<>();
        item.put("memo", "Empty Memo");
        item.put("author", "Empty Author");
        items.add(item);

        model.addAttribute("items", items);
        return "memo";
    }
}

この例では、作成済みのビューに埋め込んだ変数名 ${item.memo}"Empty Memo" を、${#strings.isEmpty(item.author) ? '' : ' @' + item.author}"Empty Author" を設定しています。

正しく動作するかどうか、念のため起動して確認しておきます。アプリケーションが起動したら、http://localhost:8080/memo へアクセスします。

./mvnw spring-boot:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building self-study-spring 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------

...

2016-05-01 21:36:34.173  INFO 92700 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-05-01 21:36:34.181  INFO 92700 --- [           main] i.g.y.sss.SelfStudySpringApplication     : Started SelfStudySpringApplication in 4.822 seconds (JVM running for 8.904)

設定した文字列が、変数箇所に埋め込まれたことが確認できました。

ビューへの値の受け渡しに使用した org.springframework.ui.Model#addAttribute(String, Object) は、このようなマップインスタンスの他に、モデルオブジェクトについても同様にビューに渡すことができます。以下を参考にモデルを作成して、これも確認してみます。

まずはモデルの作成。

// src/main/java/io/github/yo1000/sss/model/Memo.java
package io.github.yo1000.sss.model;

import java.util.Date;

public class Memo {
    private String memo;
    private String author;
    private Date created;

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }
}

続いて、コントローラーを変更していきます。

// src/main/java/io/github/yo1000/sss/controller/page/MemoController.java
package io.github.yo1000.sss.controller.page;

import io.github.yo1000.sss.model.Memo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("memo")
public class MemoController {
    @RequestMapping("")
    public String get(Model model) {
        List<Map<String, Object>> items = new ArrayList<>();
        Map<String, Object> item = new HashMap<>();
        item.put("memo", "Empty Memo");
        item.put("author", "Empty Author");
        items.add(item);

        model.addAttribute("items", items);
        return "memo";
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public String post(@ModelAttribute Memo item,
                       Model model) {
        List<Memo> items = new ArrayList<>();
        items.add(item);

        model.addAttribute("items", items);
        return "memo";
    }
}

アプリケーションを再起動して、改めて、http://localhost:8080/memo へアクセスします。今度は入力欄にそれぞれ値を入力して、Submit ボタンをクリックしてみます。

入力した値を受け取り、設定した文字列が、変数箇所に埋め込まれたことが確認できました。

他にも、いくつか値の受け取り方があるため、代表的なものを確認しておきます。コントローラーを以下のように変更します。

// src/main/java/io/github/yo1000/sss/controller/page/MemoController.java
package io.github.yo1000.sss.controller.page;

import io.github.yo1000.sss.model.Memo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("memo")
public class MemoController {
    @RequestMapping("")
    public String get(Model model) {
        List<Map<String, Object>> items = new ArrayList<>();
        Map<String, Object> item = new HashMap<>();
        item.put("memo", "Empty Memo");
        item.put("author", "Empty Author");
        items.add(item);

        model.addAttribute("items", items);
        return "memo";
    }

    @RequestMapping("param/{memo:[a-zA-Z0-9]+}")
    public String getParams(@PathVariable String memo,
                            @RequestParam(required = false, defaultValue = "Default Author") String author,
                            Model model) {
        List<Memo> items = new ArrayList<>();
        Memo item = new Memo();
        item.setMemo(memo);
        item.setAuthor(author);
        items.add(item);

        model.addAttribute("items", items);
        return "memo";
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public String post(@ModelAttribute Memo item,
                       Model model) {
        List<Memo> items = new ArrayList<>();
        items.add(item);

        model.addAttribute("items", items);
        return "memo";
    }
}

アプリケーションを再起動して、改めて、http://localhost:8080/memo/param/PathMemo?author=ReqAuthor へアクセスします。

エンドポイントに指定した値を受け取り、設定した文字列が、変数箇所に埋め込まれたことが確認できました。

今回追加で設定した、@RequestMapping("{memo:[A-Z0-9]+}")@PathVariable@RequestParam(required = false, defaultValue = "Default Author") がどのように動作するのか、以下のエンドポイントへアクセスして確認してみてください。

アノテーション

今回、新たに登場したアノテーションを簡単に説明しておきます。

@Controller

コントローラークラスに設定します。このアノテーションが設定されると、クラスが DI コンテナへの登録対象としてマークされます。このようなマーキング用アノテーションは、ステレオタイプアノテーションと呼ばれます。

@RequestMapping

コントローラークラス、およびメソッドに、エンドポイントを設定します。クラス、メソッドそれぞれに設定された場合、それらが / で繋がれたものがエンドポイントとなります。なお、エンドポイント前後の / は、Spring により自動的に 補完されるため、指定は不要です。

{} で囲んだパラメーター名に、値を受け取ることができ、@PathVariable の設定された同名の引数に値を連携します。パラメーター名の後ろに、: を続けて正規表現を設定すると、受け取るパラメーターの値を制限することができます。

method プロパティを設定することで、リクエストを受ける際の HTTP メソッドを制限したり、consumes プロパティを設定することで、リクエストを受ける際の Content Type を制限したり、produces プロパティを設定することで、レスポンスする際の Content Type を指定したりすることができます。

リクエストに対し、該当するエンドポイントが見つからなかった場合、404 Not Found がレスポンスされます。

@ModelAttribute

複数の入力値を、ひとつのモデルの、各同名フィールドに連携します。

@PathVariable

@RequestMapping で受け取った値を、コントローラーメソッドの引数に連携します。

@RequestParam

クエリパラメーターをコントローラーメソッドの引数に連携します。

required プロパティを設定することで、クエリパラメーターを任意指定としたり、defaultValue プロパティを設定することで、クエリパラメーターが指定されなかった場合のデフォルト値を設定したりできます。

参考

サンプル

ここまでのコードサンプルは、以下より入手できます。

$ git clone -b chapter/3 https://github.com/yo1000/self-study-spring.git

results matching ""

    No results matching ""