LoginSignup
5
7

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-12-07

はじめに

やりたいこと

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

この記事が参考になる人

  • お問い合わせフォームを実装する人など。
  • 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の実装をしたからすごいつまづきながらの実装だった。。

5
7
2

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
  3. You can use dark theme
What you can do with signing up
5
7