たそらぼ

日頃思ったこととかメモとか。

play 2.7.xでFormの作成

play 2.7.xでFormを作ろうと思ったら、過去バージョンと全く違うので困った。
とりあえず動くものができたのでメモ。

公式サンプル

まずはplay-java-forms-exampleというのがdocumentで公開されているので、cloneして動かしてみる。
github.com

作った画面

公式サンプルを参考にして作成。
f:id:tasotasoso:20190504231014p:plain
Formにテキストを入力してSend Textを押すと、上の表に反映される。

実装

基本的に公式サンプルと同じだが、最初わからなかったところを記載する。

画面のフォーム箇所

  @*Form*@
  @helper.form(routes.FormController.createWidget) {

    @* CSRFの対策にフィールドにトークンを入れる *@
    @helper.CSRF.formField

    @helper.inputText(form("text"))

    <button type="submit">Send Text</button>
  }

@helper.CSRF.formFieldはクロスサイトリクエストフォージェリ対策でフォームのフィールドにトークンを入れる。

Formの入力値受け取りと表示用のコントローラー

package controllers;

import models.Widget;
import models.WidgetData;

import play.data.Form;
import play.data.FormFactory;
import play.i18n.MessagesApi;
import play.mvc.*;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;

import static play.libs.Scala.asScala;

/**
 * An example of form processing.
 *
 * https://playframework.com/documentation/latest/JavaForms
 */
@Singleton
public class FormController extends Controller {

    private final Form<WidgetData> form;
    private MessagesApi messagesApi;
    private final List<Widget> widgets;

    private final Logger logger = LoggerFactory.getLogger(getClass()) ;


    @Inject
    public FormController(FormFactory formFactory, MessagesApi messagesApi) {
        this.form = formFactory.form(WidgetData.class);
        this.messagesApi = messagesApi;
        this.widgets = com.google.common.collect.Lists.newArrayList();
    }

  /**
  *初期状態の画面のレンダリング
  */
    public Result index() {
        return ok(views.html.index.render());
    }

  /**
  *Formの入力値をwidgetsに加えた後、それを表示する。
  *@param request
  */
    public Result listWidgets(Http.Request request) {
        return ok(views.html.listWidgets.render(asScala(widgets), form, request, messagesApi.preferred(request)));
    }

  /**
  *Formの入力値をwidgetsに加えた後、それを表示する。
  *@param request
  */
    public Result createWidget(Http.Request request) {
        final Form<WidgetData> boundForm = form.bindFromRequest(request);

        if (boundForm.hasErrors()) {
            logger.error("errors = {}", boundForm.errors());
            return badRequest(views.html.listWidgets.render(asScala(widgets), boundForm, request, messagesApi.preferred(request)));
        } else {
            WidgetData data = boundForm.get();
            widgets.add(new Widget(data.getText()));
            return redirect(routes.FormController.listWidgets())
                .flashing("info", "Widget added!");
        }
    }
}

こいつがかなり違う。