개발 무지렁이

[Spring Boot] 폼과 폼 Validation 본문

Backend/스프링부트

[Spring Boot] 폼과 폼 Validation

Gaejirang-e 2022. 11. 28. 10:53


폼은 URL 생성기이다.

[question_form.html]

<div class="alert alert-danger" role="alert" th:if="${subjectErrorMsg != null}" th:text="${subjectErrorMsg}"></div>
<div class="alert alert-danger" role="alert" th:if="${contentErrorMsg != null}" th:text="${contentErrorMsg}"></div>
<form th:action="@{/question/create}" method="post"> // post이고, th:action="@{}"를 붙여주면 스프링 시큐리티가 csrf토큰을 알아서 만들어준다
  <div>
    <label class="form-label">제목</label>
    <input type="text" name="subject" placeholder="제목을 입력해주세요." class="form-control">
  </div>
  <div>
    <label class="form-label">내용</label>
    <textarea name="content" placeholder="내용을 입력해주세요." rows="15" class="form-control"></textarea>
  </div>
  <input type="submit" value="등록" class="btn btn-primary my-2">
</form>

[QuestionController.java]

 ⚠️ form에서 정해준 name과 같게, Controller에서 파라미터 이름을 지정해 줘야 한다
@RequestMapping("/question")
@RequiredArgsConstructor
@Controller
public class QuestionController {
    @GetMapping("question/create") 
    public String showCreate() {
        return "question_form";
    }

    @PostMapping("question/create")
    public String create(Model model, String subject, String content) {
        boolean hasError = false;
        if(subject == null || subject.trim().length() == 0) { // 받은 정보가 null이거나 공백이라면
            model.addAttribute("subjectErrorMsg", "제목을 입력해주세요."); // 에러메세지 전송
            hasError = true;
        }

        if(content == null || content.trim().length() == 0) { 
            model.addAttribute("contentErrorMsg", "내용을 입력해주세요."); 
            hasError = true;
        }

        if(hasError) {
            return "redirect:/question/create";
        }

        questionService.create(subject, content);
        return "redirect:/question/list";
    }
}

폼 Validation


[build.gradle 🐘]

implementation 'org.springframework.boot:spring-boot-starter-validation'

[question_form.html]

<form th:action="@{/question/create}" method="post"> // post이고, th:action="@{}"를 붙여주면 스프링 시큐리티가 csrf토큰을 알아서 만들어준다
  <div class="alert alert-danger" role="alert" th:if="${#fields.hasAnyErrors()}">
    <div th:each="err : ${#fields.allErrors()}" th:text="${err}" />
  </div>                                                                                                        
  <div>
    <label class="form-label">제목</label>
    <input type="text" th:field="*{subject}" placeholder="제목을 입력해주세요." class="form-control">
  </div>
  <div>
    <label class="form-label">내용</label>
    <textarea th:field="*{content}" placeholder="내용을 입력해주세요." rows="15" class="form-control"></textarea>
  </div>
  <input type="submit" value="등록" class="btn btn-primary my-2">
</form>

[QuestionForm.java]

@AllArgsConstructor
@Getter
public class QuestionForm {
    @NotEmpty(message="제목을 입력해주세요.")
    @Size(max=200, message="제목을 200자 이하로 입력해주세요.")
    private String subject;

    @NotEmpty(message="내용을 입력해주세요.")
    private String content;
}

[QuestionController.java]

@RequestMapping("/question")
@RequiredArgsConstructor
@Controller
public class QuestionController {
    @GetMapping("question/create") 
    public String showCreate(QuestionForm questionForm) {
        return "question_form";
    }

    @PostMapping("question/create")
    public String create(Model model, @Valid QuestionForm questionForm, BindingResult bindingResult) {
           if(bindingResult.hasErrors()) {
             return "question_form";
           }
        questionService.create(questionForm.getSubject(), questionForm.getContent());
        return "redirect:/question/list";
    }
}
 ⚠️ 문제가 되는 정보는 BindingResult에 들어간다
    [field(입력상자) error / 일반 error]

  • .hasErrors()
  •   -> 문제가 있으면 true 리턴

  • .rejectValue("(input name)", ErrorCode, ErrorMessage)
  •   -> field error, (input name) 해당 입력상자에 연관지어 그 밑에 ErrorMessage가 뜬다.

  • .reject(ErrorCode)
  •   -> 일반 error
Comments