search
LoginSignup
6

More than 1 year has passed since last update.

posted at

updated at

【Spring】入力フォームを実装する(入力画面⇒確認画面⇒完了画面)

はじめに

やりたいこと

  • ユーザがフォームに入力した値をもとに何かしたい。
  • 入力画面⇒確認画面⇒完了画面、と遷移させたい。

この記事が参考になる人

  • お問い合わせフォームを実装する人など。
  • Java, Spring, Thymeleafの知識が最低限ある人。

使った技術要素

  • Java
  • Spring
    • フレームワーク
  • Thymeleaf
    • テンプレートエンジン
  • lombok
    • getter, setterを自動生成してくれる

実装

好みもあるかと思いますが、以下の手順で実装していくといいと思います。
最低限のスニペットのみ掲載します。

入力画面

HTML

input.html
<blc:form  th:action="@{/input}" method="POST" name="hogeForm" th:object="${hogeForm}">
    <p>問い合わせカテゴリー</p>
    <select name="category" th:field="*{category}">
        <option value="">---</option>
        <option th:each="item : *{getCategoryList()}" th:value="${item.key}" th:text="${item.value}"/>
    </select>
    <p th:if="${#fields.hasErrors('category')}" th:errors="*{category}">エラーメッセージ</p>

    <p>問い合わせ内容</p>
    <textarea name="content" placeholder="お問合せ内容を入力してください。" th:field="*{content}"></textarea>
    <p th:if="${#fields.hasErrors('content')}" th:errors="*{content}">エラーメッセージ</p>

    <input type="submit" value="確認"/>
</blc:form>

Formオブジェクト

HogeForm.java
@Getter
@Setter
public class HogeForm implements Serializable {
    @NotBlank(message="選択してね")
    private String category;

    @NotBlank(message="何か入力してね")
    @Length(max=1000)
    private String content;

    public Map<String, String> getCategoryList() {
    Map<String, String> categoryMap = new LinkedHashMap<String, String>();
        categoryMap.put("1", "カテゴリー1");
        categoryMap.put("2", "カテゴリー2");
        categoryMap.put("3", "カテゴリー3");
        return categoryMap;
    }
}

ポイント

  • プロパティ名とformのname属性は同じ変数名を使う。
  • getCategoryList()でセレクトボックスの内容はFormで保持しておく。順番に表示したいから LinkedHashMapを使う。 HTML側での表示方法は以下の通り。
<option th:each="item : *{getCategoryList()}" th:value="${item.key}" th:text="${item.value}"/>
  • Validationでエラーになった時、
    • HTML側にて#fields.hasErrors('(プロパティ名)')trueになる。
    • @(Validationタイプ)(message="~~~")とプロパティにmessageを指定しておくと、HTML側でth:errors="*{(プロパティ名)}"と記述すれば、指定したmessageを表示することができる。

Controller

HogeController.java
@RequestMapping("/input")
public ModelAndView input(
        @ModelAttribute("hogeForm") HogeForm hogeContactForm,
        Model model, HttpServletRequest request) {

    return "index.html";
}

@RequestMapping(value = "/input", method = RequestMethod.POST)
public ModelAndView input(
        @Valid @ModelAttribute("hogeForm") HogeForm hogeForm,
        BindingResult bindingResult,
        Model model, HttpServletRequest request) {

    // エラーがある場合、自画面遷移する
    if (bindingResult.hasErrors()) {
        return "index.html";
    }

    HttpSession session = request.getSession();
    session.setAttribute("hogeForm", hogeForm);
    return "redirect:/confirm";
}

ポイント

  • formのPOST先を確認画面(/confirm)にするのではなく、それ用に2つ目のinputメソッドを作成する。
    • メリット:/confirm のメソッドが確認画面の表示に専念できる。
    • POST先を/confirmにしてしまうと、confirmメソッド内で入力画面用の処理と確認画面用の処理の2つを実装しなくてはならなくなってしまう。
    • 上記はシンプル例だからそんなにメリットを感じられないが、実業務だとコードがすっきりしていい感じになる。

確認画面

HTML

confirm.html
<blc:form  th:action="@{/complete}" method="POST" name="hogeForm" th:object="${hogeForm}">
    <p>問い合わせカテゴリー</p>
    <p th:text="*{getCategoryList().get('__*{category}__')}">カテゴリー1</p>

    <p>問い合わせ内容</p>
    <p th:text="*{content}">ここに問合せ内容を表示</p>

    <div>
        <input type="hidden" name="category" th:value="*{category}" />
        <input type="hidden" name="content" th:value="*{content}" />
        <input type="submit" value="送信" />
    </div>
</blc:form>

ポイント

  • *{getCategoryList().get('__*{category}__')}でMapのvalueを表示できる。普通に*{category}だけだとkeyの方が表示される。

Controller

HogeController.java
@RequestMapping("/confirm")
public ModelAndView confirm(
        Model model, HttpServletRequest request) {

    HttpSession session = request.getSession();
    HogeForm hogeForm = (HogeForm) session.getAttribute("hogeForm");
    model.addAttribute("hogeForm", hogeForm);
    return "confirm.html";
}

完了画面

HTML

complete.html
<p>以下の内容で受け付けました。</p>

<p>問い合わせカテゴリー</p>
<p th:text="*{getCategoryList().get('__*{category}__')}">カテゴリー1</p>

<p>問い合わせ内容</p>
<p th:text="*{content}">ここに問合せ内容を表示</p>
</blc:form>

Controller

HogeController.java
@RequestMapping("/complete")
public ModelAndView complete(
        @ModelAttribute("hogeForm") HogeForm hogeContactForm,
        Model model, HttpServletRequest request) {

    model.addAttribute("hogeForm", hogeForm);
    return "complete.html";
}

感想

2年ぶりくらいにformの実装をしたからすごいつまづきながらの実装だった。。

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
What you can do with signing up
6