[Spring] Todo 검증기능(2) - 유효성 검사 결과(BindingResult 객체)를 form tag library의 <form:errors> 태그로 에러메시지 띄우는 방법

민지·2024년 2월 6일
0

SpringBoot, Spring MVC에서의 검증 - 4단계

이전 포스팅에서 스프링부트에서의 검증을 다음과 같은 총 4가지 단계에 대해 배웠다.

1. Spring Boot Starter Validation

  • pom.xml에 의존성 주입 추가

2. Command Bean/Form Backing Object 개념 사용

  • 2-way binding(양방향 바인등) 가능 (todo.jsp - TodoController.java끼리의 바인딩 가능)

3. Bean에 검증 추가 - Todo.java에 추가할 것

  • description field의 최소 문자 개수 10개임을 추가할 것
  • deadline field - 항상 현재 날짜 또는 미래날짜만 가능하게끔

4. 검증 에러를 뷰에 표시할 것 - addTodo.jsp에 추가

앞선 포스팅에서 배웠던 "양방향" 바인딩에 대해 정리를 해보겠다.

첫번째 방향내가 작성한 자바코드의 Bean -> form 양식으로의 바인딩 이다. 다시 말해, showNewTodoPage()메서드에서 작성한 todo 객체는 디폴트로 ""으로 초기화되기에, addTodo.jsp에서도 공백으로 표시되는 것으로 생각할 수 있다.

반대로, 두 번째 방향은 내가 form 양식에서 입력한 값이 -> 내가 작성한 자바코드의 Bean으로의 바인딩이다. 다시 말해, addTodo.jsp에서 입력한 description값이 -> addNewTodoPage()메서드의 Todo 객체로의 바인딩됨을 뜻한다. 참고로, path 속성을 통해 바인딩될 자바 객체의 위치를 찾을 수 있다.

이제 양방향 바인딩의 의미까지 정확히 되짚었으니, 검증 3,4단계로 넘어가보자. 즉 Bean에 검증을 추가하고, 해당 검증 에러를 뷰에 표시해보자!

결론부터 말하자면, 이번 포스팅은 유효성 검사한 결과(BindingResult 객체)를, Form Tag Library에 있는 form:error태그를 사용해, 웹페이지에서 처리하는 방법을 배우는 과정을 정리할 것이다.

검증 3 : Bean에 검증 추가 - @Size, @Valid

Todo.java와 TodoController 코드 리팩토링

// Todo.java -> 검증을 추가한 코드 부분만
public class Todo {
	private int id;
	private String username;
	@Size(min = 10, message = "Enter at least 10 characters")
	private String description;
	private LocalDate deadline;
	private boolean Done;
	
	.
	.
	.
}

// TodoController.java
// add-todo - POST
	@RequestMapping(value = "/add-todo", method = RequestMethod.POST)
	public String addNewTodoPage(ModelMap model, @Valid Todo todo) {

	String username = (String) model.get("name");
	todoService.AddTodo(username, todo.getDescription(), LocalDate.now().plusYears(1), false);
		return "redirect:list-todos";
	}

멤버변수 description에 @Size 어노테이션을 추가해 최소 글자가 10이 되게끔 하고, 해당 검증에 실패한다면 뜨게 될 message값도 설정했다.

해당 검증 관련 클래스들은 jakarta.validation API 아래에 다양하게 존재한다.

또한 TodoController에는 @Valid어노테이션을 추가했다. @Valid 어노테이션을 추가하면, spring form tag library를 통해 jsp의 <form:form> todo 객체컨트롤러 메서드의 todo 객체가 바인딩되기 에, Todo Bean을 검증하게 된다!

해당 검증 실행결과,

다음과 같이 검증이 잘 실행된 것을 확인할 수 있다!

하지만 해당 에러 404 페이지가 뜨는 걸 원하는 게 아니라, 에러 메세지가 따로 화면 뷰에 뜨길 원했다.

검증 4 : 검증 에러를 뷰 화면에 표시할 것 - BindingResult, <form:errors>

BindingResult.hasErrors()메서드로, 에러 발생 시 addTodo.jsp 뷰를 띄울 것

// add-todo - POST
	@RequestMapping(value = "/add-todo", method = RequestMethod.POST)
	public String addNewTodoPage(ModelMap model, @Valid Todo todo, BindingResult result) {

		if (result.hasErrors()) {
			return "addTodo";
		}
		String username = (String) model.get("name");
		todoService.AddTodo(username, todo.getDescription(), LocalDate.now().plusYears(1), false);
		return "redirect:list-todos";
	}
  • BindingResult result의 hasErrors메서드를 이용해, 어떠한 에러(검증 오류)가 1개라도 있다면, list-todos redirect되는 것이 아니라, 다시 addTodo.jsp로 돌아가게끔 했다.

하지만 해당 코드만 수정하면, 화면에 에러메세지가 안 떴다.

<form:errors>로 에러 메세지 띄우기

@Valid를 통한 유효성 검사할 때 발생한 오류 메세지를 JSP 뷰 페이지에 출력하려면, 앞서 배운 spring form tag library 중, <form:errors> 태그를 사용해야 한다.

<form:errors> 예제코드

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
	<head>
		<title>Validation</title>
	</head>
<body>
    <h3>유효성 검사</h3>

    <form:form modelAttribute="product" method="post">
        <p>품명 : <form:input path="name"/> <form:errors path="name"/><p>가격 : <form:input path="price"/> <form:errors path="price"/><p><input type="submit" value="확인"/> 
        <input type="reset" value="취소"/>
    </form:form>
</body>
</html>
  • <form:errors>를 통해, 멤버변수 name과 price에 대한 오류 메시지를 출력한다.

<form:errors>를 이용한 addTodo.jsp 코드 리팩토링

// <form:errors>를 추가한 addTodo.jsp
<body>
		<div class = "container">
			<h1>Enter Todo Details</h1>
			<form:form method = "post" modelAttribute="todo">
				Description : <form:input type = "text" path="description" name = "description" required = "required" /> 
							  <form:errors path = "description" /> <br>
				<form:input type = "hidden" path="id"/> <br>
				<form:input type = "hidden" path="done"/> <br>
				<input type = "submit" class = "btn btn-success"/>
			</form:form>
			<script src="webjars/bootstrap/5.1.3/js/bootstrap.min.js"></script>
			<script src="webjars/jquery/3.6.0/jquery.min.js"></script>
		</div>
</body>


실제로 description에 대한 검증에 오류가 나자(문자 개수 10미만인 5개였음), 해당 에러 메시지가 add-todo 화면에 뜨게 됐다.

하지만 해당 경고 메세지가 예쁘지 않으니, CSS 클래스를 추가해보자.

addTodo.jsp에 CSS 클래스 추가 - Spring tag는 cssClass 속성 이용

<body>
		<div class = "container">
			<h1>Enter Todo Details</h1>
			<form:form method = "post" modelAttribute="todo">
				Description : <form:input type = "text" path="description" name = "description" required = "required" /> 
							  <form:errors path = "description" cssClass = "text-warning"/> <br>
				<form:input type = "hidden" path="id"/> <br>
				<form:input type = "hidden" path="done"/> <br>
				<input type = "submit" class = "btn btn-success"/>
			</form:form>
			<script src="webjars/bootstrap/5.1.3/js/bootstrap.min.js"></script>
			<script src="webjars/jquery/3.6.0/jquery.min.js"></script>
		</div>
</body>

원래 HTML에 class를 추가할 때는, <input class="" />처럼, 클래스를 추가했다.

하지만! spring form tag는 HTML 태그가 아닌, 스프링 태그이다. spring tag에서는 클래스를 추가할 때, class 대신 cssClass 속성을 사용한다.

cssClass = "text-warning"에서 "text-warning"은 Bootstrap에서 제공하는 클래스이다.

실행결과, 글자에 색을 입혀 경고메시지처럼 띄워졌다.




출처 :

https://thebook.io/080266/0460/
이 시리즈는 Udemy 강의의 내용을 정리한 것입니다.
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/

profile
배운 내용을 바로바로 기록하자!

0개의 댓글