티스토리 뷰
지난 포스팅에서는 사용자의 입력을 받아 데이터를 저장하고 저장된 결과 목록을 AJAX로 받아와 원하는 fragments에 보여지도록 하였다.
이번에는 사용자의 입력을 받을 때 입력값이 valid한지를 체크하는 예제를 생성해보려고 한다.
자바스크립트로 처리할 수 있는 부분이지만 스프링부트와 타임리프를 쓸 때는 어떻게 하는지에 대해서도 알아두면 좋지 않을까 생각한다.
validation 체크를 하기 위한 예제로 test8로 요청하면 처리할 컨트롤러와 test8.html을 생성하겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package com.joyhong.controller;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import com.joyhong.domain.Book;
import com.joyhong.service.BookService;
@Controller
public class TestController2 {
private Logger logger = LoggerFactory.getLogger(TestController.class);
@Autowired
private BookService bookService;
public String test8(Model model, Book book) {
return "test/test8";
}
public String checkBook(Model model, @Valid Book book, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "test/test8 :: #form";
}
bookService.createBook(book);
model.addAttribute("bookMap", bookService.readBookAll());
return "test/test8 :: #list";
}
}
|
/test8요청은 GET방식으로 들어올 때와 POST 방식으로 들어올 때를 구분하여 각각 하나씩 생성하였다.
GET방식으로 들어오는 경우는 처음 진입할 사용되어지고, 입력버튼을 누르게 되면 POST 방식으로 넘기도록 할 것이기 때문에 이 때 사용된다. valid 체크도 POST 방식으로 넘어오게 된다.
그래서 GET 방식으로 test8 요청이 들어오면 단순히 test8.html을 화면에 보여주게 되는데 test8.html은 아래와 같이 생성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div>
<h3>Validation Check</h3>
<p>책 정보 입력</p>
<form id="form" th:object="${book}">
<table>
<tr>
<td>책제목</td>
<td>
<input type="text" th:field="*{title}" placeholder="책 제목을 입력하세요">
</td>
<td class="err" th:if="${#fields.hasErrors('title')}" th:errors="*{title}">Name Error</td>
</tr>
<tr>
<td>저자명</td>
<td>
<input type="text" th:field="*{creator}" placeholder="저자명을 입력하세요">
</td>
<td class="err" th:if="${#fields.hasErrors('creator')}" th:errors="*{creator}">Name Error</td>
</tr>
<tr>
<td>출판사</td>
<td>
<input type="text" th:field="*{publisher}" placeholder="출판사명을 입력하세요">
</td>
<td class="err" th:if="${#fields.hasErrors('publisher')}" th:errors="*{publisher}">Name Error</td>
</tr>
<tr>
<td>출판연도</td>
<td>
<input type="text" th:field="*{publishedYear}">
</td>
</tr>
</table>
<button type="button" onclick="inputData2(this)" >입력</button>
</form>
</div>
<div id="list">
<th:block th:if="${bookMap != null}">
<h3>책 목록</h3>
<table border=1>
<tr>
<th>번호</th>
<th>제목</th>
<th>저자</th>
<th>출판사</th>
<th>출판연도</th>
</tr>
<td th:text="${book.creator}"></td>
<td th:text="${book.publisher}"></td>
<td th:text="${book.publishedYear}"></td>
</tr>
</table>
</th:block>
</div>
</body>
</html>
|
form태그에서는 th:object="${book}" 을 지정하여 Book 클래스에 매핑되도록 하였고 th:field를 사용하여 Book 클래스의 변수들을 지정하였다. 사용자가 폼에 값을 입력하고 입력 버튼을 누르면 inputData2() 라는 자바스크립트 함수에서 처리하게 하였는데 자바스크립트는 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
function inputData2(){
var book = $('#form').serialize();
$.ajax({
url: "/home/test8",
data: book,
type:"POST",
cache: false
}).done(function (fragment) {
if ($(fragment).find("#form").prevObject["0"].length > 0) {
$("#form").replaceWith(fragment);
}
else{
$("#list").replaceWith(fragment);
$("input[type=text]").val("");
$('.err').text("");
}
});
}
|
폼의 값을 test8에 POST 방식으로 넘기는데 결과에 따라 화면에서 변경되는 값이 달라지도록 하였다. 이는 컨트롤러에서 먼저 살펴보면, test8에 대한 POST 방식을 처리할 때
@Valid Book book 를 사용하여 Book 클래스에 매핑된 값이 valid 한지를 체크하는 어노테이션을 붙였고,
BindingResult bindingResult 를 사용하여 validation 체크결과가 담긴 객체를 통해
bindingResult.hasErrors() 가 true이면 즉, 에러가 있으면 test8.html에 id가 form 인 부분을 내용을 바꾸도록 하였다.
그리고 false 이면 book 객체의 값을 업무로직에 보내 저장하고 다시 전체 목록을 받아와 test8.html에 id가 list 인 부분의 내용을 바꾸도록 하였다.
따라서 위의 자바스크립트에서는 form에 대한 내용이면 그 부분을 변경하고,
아니면 list 부분을 변경하고 input 태그의 값을 지우고, err 클래스인 텍스트값을 없애도록 하였다.
그럼 이제 Book 클래스의 내용을 조금 손 봐야 한다.
컨트롤러에서 주고 받는 Book 클래스에는 Validation을 위한 어노테이션이 들어가야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package com.joyhong.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class Book {
private long seq;
@NotBlank(message="제목은 반드시 입력해야 합니다.")
private String title;
@NotBlank(message="저자는 반드시 입력해야 합니다.")
private String creator;
@NotNull
@Size(min=2, message="두 글자 이상 입력해야 합니다.")
private String publisher;
private int publishedYear;
public long getSeq() {
return seq;
}
public void setSeq(long seq) {
this.seq = seq;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public int getPublishedYear() {
return publishedYear;
}
public void setPublishedYear(int publishedYear) {
this.publishedYear = publishedYear;
}
}
|
여기서는 제목, 저자명, 출판사에 대해서만 valid한지를 체크하도록 하였는데
@NotBlank 을 사용하여 null을 허용하지 않도록 한 것과
@NotNull 을 사용하여 null과 공백문자열을 허용하지 않도록 한것
그리고 @Size 을 통해 길이에 대한 제한을 둔 것 을 사용하였다.
이외에도 여러가지가 있는데 자세한 내용을 공식 사이트를 참조하면 좋을 것 같다.
그리고 message에 valid하지 않을 경우에 대한 메세지를 입력하면 된다.
그럼 이제 결과를 확인해보면
'SpringBoot+Thymeleaf' 카테고리의 다른 글
AJAX로 화면 내용 바꾸기 (8) | 2020.02.18 |
---|---|
타임리프로 뷰페이지 만들기 - Form (폼) (0) | 2020.02.17 |
타임리프로 뷰페이지 만들기 - 기본 문법 (0) | 2020.02.12 |
Controller 생성하기 (0) | 2020.02.11 |
업무로직 만들기 (0) | 2020.02.10 |
- Total
- Today
- Yesterday
- stardog
- RDF 변환
- Knowledge Graph
- rdfox
- 트리플 변환
- 트리플
- 지식그래프
- LOD
- 사이퍼
- django
- Thymeleaf
- sparql
- Linked Data
- 지식 그래프
- RDF
- networkx
- TopBraid Composer
- property graph
- Neo4j
- pyvis
- 그래프 데이터베이스
- 온톨로지
- Ontology
- TBC
- cypher
- neosemantics
- TDB
- 타임리프
- 장고
- 스프링부트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |