study-note

フォーム送信 / バリデーション

目次

概要

処理の流れ

HTMLフォーム → DTO(Formクラス) → Controller → Service → Repository

バリデーションの流れ

  1. @Validで自動検証
  2. エラーがあればBidingResultに格納
  3. 問題なければService層へ

基本構文

フォームクラス定義(DTO形式)

import jakarta.validation.constraints.*;

public class UserForm {

  @NotBlank(message = "名前を入力してください")
  private String name;

  @Min(value = 0, message = "年齢は0以上でなければなりません")
  @Max(value = 120, message = "年齢は120以下でなければなりません")
  private int age;

  @Email(message = "メールアドレスの形式が不正です")
  private String email;

  // getter / setter 省略
}

Controllerでフォームを受け取る

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

  private final UserService userService;
  public UserController(UserService userService) {
    this.userService = userService;
  }

  // POSTフォーム受け取り
  @PostMapping("/register")
  public String registerUser(@RequestBody @Valid UserForm form, BindingResult result) {
    if (result.hasErrors()) {
      // バリデーションエラー内容を返す
      return result.getAllErrors().toString();
    }
    userService.createUser(form);
    return "登録成功!";
  }
}

サービス層で処理を実行

import org.springframework.stereotype.Service;

@Service
public class UserService {

  private final UserRepository repository;
  public UserService(UserRepository repository) {
    this.repository = repository;
  }

  public void createUser(UserForm form) {
    User user = new User();
    user.setName(form.getName());
    user.setAge(form.getAge());
    user.setEmail(form.getEmail());
    repository.save(user);
  }
}

Thymeleafを使う場合の例

<form th:action="@{/users/register}" method="post" th:object="${userForm}">
  <input type="text" th:field="*{name}" placeholder="名前">
  <input type="number" th:field="*{age}" placeholder="年齢">
  <input type="email" th:field="*{email}" placeholder="メール">
  <button type="submit">送信</button>

  <div th:if="${#fields.hasErrors('*')}">
    <ul>
      <li th:each="err : ${#fields.errors('*')}" th:text="${err}"></li>
    </ul>
  </div>
</form>

フォームクラス定義における主なアノテーション


→ 次:例外処理