超基本的な内容です(自分の備忘録)。
画面のあるWebアプリを開発していると、画面での入力値をPOSTしてサーバ側で受け取りその値を新規登録・更新・削除、、、なんてのがよくあると思います。本記事は、SpringではPOSTした値をサーバ側で受け取る時にどのような実装になるのか、というお話です。
ちなみにSAStrutsなんかだと、その部分の実装は以下のような感じです。
@ActionForm
@Resource
protected AddForm addForm;
@Execute
public String add() {
// 何らかの処理
String id = addForm.id;
// 何らかの処理
return "list.jsp?redirect=true";
}
@ActionFormアノテーション、@Resourceアノテーションをつけるだけで、自動的にPOSTされた値がaddFormオブジェクトの各フィールドにマッピングされ、対象のExecuteメソッドの中で利用出来るようになります。
ここでは、画面上に苗字(firstName)、名前(lastName)の2つのテキストボックスがあるものとして、これらをPOSTしてみる、、というのを例にまとめてみます。
Formクラスの作成
まずは、画面上での入力値を保持するFormクラスの作成が必要です(このあたりは他のFWとかも一緒ですね)。ただSAStrutsしかやったことのない人、注意が必要です、このFormクラスはsetter/getterが必要になってきます。
package com.example.form;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class CustomerForm {
@NotNull
@Size(min = 1, max = 127)
private String firstName;
@NotNull
@Size(min = 1, max = 127)
private String lastName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
ちなみに、setter/getterを作ってあげないと、以下みたいな感じで実行時に怒られます。
org.springframework.beans.NotReadablePropertyException: Invalid property 'lastName' of bean class [com.example.form.CustomerForm]: Bean property 'lastName' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
ControllerクラスでFormを受け取る
画面上での入力値を保持するFormクラスをControllerクラスで受け取ってみます。
package com.example.web;
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.domain.Customer;
import com.example.form.CustomerForm;
import com.example.service.CustomerService;
@Controller
@RequestMapping("customers")
public class CustomerController {
@Autowired
CustomerService customerService;
@ModelAttribute
CustomerForm setUpForm() {
return new CustomerForm();
}
~略~
@RequestMapping(value = "create", method = RequestMethod.POST)
String create(@Validated CustomerForm form, BindingResult result, Model model) {
if (result.hasErrors()) {
return list(model);
}
Customer customer = new Customer();
BeanUtils.copyProperties(form, customer);
customerService.create(customer);
return "redirect:/customers";
}
~略~
}
- @ModelAttributeアノテーションを利用して、受け取りたいFormクラスを初期化してreturnします。このアノテーションがついているメソッドは、このクラスのRequestMappingアノテーションがついたいずれかのメソッド実行前に呼ばれます(そのメソッドの中でそのFormを利用している・していないは関係なし)。なお、このアノテーションが付いたメソッドの戻り値は自動でリクエストスコープに設定され(つまり、JSPやThymeleafから参照できる)、Modelオブジェクトに追加されます。Modelオブジェクトに追加される時の属性名はデフォルトで、クラス名の先頭を小文字にした値になります。Modelオブジェクトとは、Springが用意するMapオブジェクトで、Viewに渡すオブジェクトを設定します。
- 実際にFormを利用するメソッド(ここではcreateメソッド)の引数でFormクラスのインスタンスを受け取ります(この時点で既にFormには画面上での入力値は入っている状態です)。
以上です。