쌓고 쌓다

[스프링 부트] 게시글 작성 유효성 검사 및 폼 데이터 유지 - 6 본문

프로그래밍/spring

[스프링 부트] 게시글 작성 유효성 검사 및 폼 데이터 유지 - 6

승민아 2023. 6. 30. 13:58

1.  폼 입력 값 유지

PosterController

@Controller
public class PosterController {

    ...
    
    @GetMapping("/poster/write")
    public String writeForm(Model model) {
        model.addAttribute("poster", new Poster());
        return "posters/createPosterForm";
    }

}

우선 게시글 작성 페이지를 위한 컨트롤러에서

게시글 객체를 생성하여 함께 게시글 작성 페이지로 넘어가게 한다.

 

createPosterForm.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/poster/write" method="post" th:object="${poster}">
    <label>제목</label>
    <input type="text" name="title" th:field="*{title}"><br>
    
    <label>작성자</label>
    <input type="text" name="writer" th:field="*{writer}"><br>

    <label>내용</label>
    <textarea type="text" name="content" th:field="*{content}"></textarea><br>

    <button type="submit">제출</button>
</form>
</body>
</html>

th:object

th:object로 form 내에 사용할 객체를 지정한다.

<form action="/poster/write" method="post" th:object="${poster}">

th:field

th:field 속성은 th:object에 설정해 준 객체의 필드와 매핑해 준다.

<input type="text" th:field="*{datePlanted}" />

<input>, <select> or <textarea> 태그에 적용이 가능하다.

 

아래의 코드와 유사하다.

<input type="text" id="datePlanted" name="datePlanted" th:value="*{datePlanted}" />

 

동작 결과

유지 결과를 보기 위해 제출 버튼 Post 동작시 다시 게시글 작성 폼으로 이동하게 변경함.

 

 

 

2.  게시글 유효성 검사

@Valid 어노테이션 사용을 위해 아래의 의존성을 추가하자.

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

 

Poster

@Entity
public class Poster {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "제목을 입력하세요.")
    private String title;

    @NotBlank(message = "작성자를 입력하세요.")
    private String writer;


    @NotBlank(message = "내용을 입력하세요.")
    private String content;

    private LocalDateTime regdate;
}

유효성 검사가 필요한 필드에 아래의 어노테이션을 사용한다.

많은 종류가 있지만 게시글을 위한 두 개만 보자...

 

@NotEmpty Null, 빈 문자열 불가능
@NotBlank Null, 빈 문자열, 스페이스(공백)만 있는 문자열 불가능

 

PosterController

@Controller
public class PosterController {

    ...
    
    @PostMapping("/poster/write")
    public String write(@Valid Poster poster, Errors errors) {

        if(errors.hasErrors()) {
            return "posters/createPosterForm";
        }

        poster.setRegdate(LocalDateTime.now());
        posterService.write(poster);
        return "redirect:/";
    }

}

POST 요청을 처리하는 메소드에 Poster 가 넘어온다.

여기에 @Valid 어노테이션을 붙여주자.

그리고 errors 객체도 받자. 이 객체에 다양한 메소드가 있다.

hasErrors() 메소드로 유효성을 통과하지 못했는지 확인할 수 있다.

에러가 있을 경우 다시 게시글 작성 폼으로 돌아가게 했다. 이전에 데이터를 유지하게 했기에 데이터 또한 유지된다.

 

createPosterForm

<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/poster/write" method="post" th:object="${poster}">
    <label>제목</label>
    <input type="text" name="title" th:field="*{title}">
    <span th:errors="*{title}"></span><br>

    <label>작성자</label>
    <input type="text" name="writer" th:field="*{writer}">
    <span th:errors="*{writer}"></span><br>

    <label>내용</label>
    <textarea type="text" name="content" th:field="*{content}"></textarea>
    <span th:errors="*{content}"></span><br>

    <button type="submit">제출</button>
</form>
</body>
</html>

 

th:errors

해당 필드가 유효성 검사에서 통과하지 못했을 때 메시지를 출력해 준다.

보통 아래의 if문과 함께 사용한다고 하는데 그냥 돌아가더라...

 

Poster 클래스에서 작성한 에러 메시지가 아닌 메시지를 출력하고 싶다면 아래와 같이 작성하자.

<p th:if="${#fields.hasErrors('title')}"> 제목을 입력하세요. </p>>

 

최종 결과

 

타임리프 문법 : https://www.thymeleaf.org/doc/tutorials/3.1/thymeleafspring.html

Comments