コントローラーの作成 - @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")
がどのように動作するのか、以下のエンドポイントへアクセスして確認してみてください。
- http://localhost:8080/memo/param/PathMemo
- http://localhost:8080/memo/param/Path_Memo?author=Req_Author
- http://localhost:8080/memo/param/?author=ReqAuthor
アノテーション
今回、新たに登場したアノテーションを簡単に説明しておきます。
@Controller
コントローラークラスに設定します。このアノテーションが設定されると、クラスが DI コンテナへの登録対象としてマークされます。このようなマーキング用アノテーションは、ステレオタイプアノテーションと呼ばれます。
@RequestMapping
コントローラークラス、およびメソッドに、エンドポイントを設定します。クラス、メソッドそれぞれに設定された場合、それらが /
で繋がれたものがエンドポイントとなります。なお、エンドポイント前後の /
は、Spring により自動的に 補完されるため、指定は不要です。
{}
で囲んだパラメーター名に、値を受け取ることができ、@PathVariable
の設定された同名の引数に値を連携します。パラメーター名の後ろに、:
を続けて正規表現を設定すると、受け取るパラメーターの値を制限することができます。
method
プロパティを設定することで、リクエストを受ける際の HTTP メソッドを制限したり、consumes
プロパティを設定することで、リクエストを受ける際の Content Type を制限したり、produces
プロパティを設定することで、レスポンスする際の Content Type を指定したりすることができます。
リクエストに対し、該当するエンドポイントが見つからなかった場合、404 Not Found
がレスポンスされます。
@ModelAttribute
複数の入力値を、ひとつのモデルの、各同名フィールドに連携します。
@PathVariable
@RequestMapping
で受け取った値を、コントローラーメソッドの引数に連携します。
@RequestParam
クエリパラメーターをコントローラーメソッドの引数に連携します。
required
プロパティを設定することで、クエリパラメーターを任意指定としたり、defaultValue
プロパティを設定することで、クエリパラメーターが指定されなかった場合のデフォルト値を設定したりできます。
参考
- http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-stereotype-annotations
- http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-controller
サンプル
ここまでのコードサンプルは、以下より入手できます。
$ git clone -b chapter/3 https://github.com/yo1000/self-study-spring.git