[스프링부트, 타임리프(Thymeleaf)로 파일게시판 만들기]
#6 Thymeleaf로 HTML페이지 작성 - 목록 출력, 게시글 작성
Thymeleaf를 이용해 HTML 페이지를 작성하려 합니다. 먼저 template 폴더에 하위폴더로 fileBoard폴더를 생성하세요.
여기에 Thymeleaf로 작업한 HTML페이지를 넣을겁니다. 이 폴더를 작성한 이유는 Controller에서 이 경로로 요청을 받겠다고 작성했기 때문입니다. 지난글에서 작성한 컨트롤러를 잠깐 확인해볼까요?
@Controller
@RequestMapping("/fileBoard")
public class FileBoardController {
@Autowired
FileBoardService fboardService;
@RequestMapping("/list")
private String fileBoardList(Model model, HttpServletRequest request) {
...
}
...
}
이렇듯 fileBoard/list, fileBoard/detail 등 fileBoard를 통해서 요청받아 작업을 수행하도록 작성했습니다. @RequestMapping 어노테이션 옆 괄호에 작성한 value값을 기준으로 HTML 페이지를 작성하겠습니다. <html>태그에 Thymeleaf 관련 속성을 작성해줍니다. list부터 작성하겠습니다.
List(게시판 목록 불러오기) 작성
list.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>파일게시판-리스트페이</title>
<style type="text/css">
li {
list-style: none;
float: left;
}
</style>
</head>
<body>
<div>
<div style="padding: 10px; text-align: center;">
<h1><a th:href="@{/fileBoard/list}" style="text-decoration: none;">파일자료실</a></h1>
</div>
<!--/* 타임리프 관련 태그에 내용이 없어도 무적권 에러ㅇㅅㅇ */-->
<div>
<table>
<thead style="text-align: center;">
<tr>
<th style="text-align: center;">순서</th>
<th style="text-align: center;">작성자</th>
<th style="text-align: center;">제목</th>
<th style="text-align: center;">작성일</th>
</tr>
</thead>
<tbody>
<tr th:each="data : ${testlist}" th:onclick=
"'window.location.href = \'' + @{/fileBoard/detail/{bno}(bno=${data.b_no})} + '\''">
<td th:text="${data.b_no}" style="cursor: pointer; text-align: center;"></td>
<td th:text="${data.writer}" style="cursor: pointer; text-align: center;"></td>
<td th:text="${data.title}" style="cursor: pointer; text-align: center;"></td>
<td th:text="${data.reg_date}" style="cursor: pointer; text-align: center;"></td>
</tr>
</tbody>
</table>
</div>
<div style="text-align: right;">
<button onclick="location.href='/fileBoard/insert'">글작성</button>
</div>
<br/><br/><br/>
</div>
</body>
</html>
작성했다면 STS4에서 서버를 실행하고, 브라우저 주소창에 localhost:8080/fileBoard/list 를 검색해보세요. 보통 Tomcat 포트번호가 8080이지만, 다른 번호를 사용하신다면 그 번호로 변경하고 접속하시면 됩니다. 이상이 없다면 아래와 같이 화면이 출력됩니다.
하하하하핳ㅎㅎㅎㅎㅎ.... 너무나 형편없습니다. CSS가 필요한 부분입니다. 뭐 부트스트랩으로 작성할거니 일단 눈물을 거두고... 일단 Database에 있는 데이터가 잘 출력되는지 확인하기 위해 Terminal에서 이전에 생성한 테이블에 데이터를 삽입해보겠습니다.
mysql> insert into file_board(title, content, writer) values('안녕하세요', '별 내용 없어요', '운영자');
Query OK, 1 row affected (0.01 sec)
mysql> select * from file_board;
+------+-----------------+----------------------+-----------+---------------------+
| b_no | title | content | writer | reg_date |
+------+-----------------+----------------------+-----------+---------------------+
| 1 | 안녕하세요 | 별 내용 없어요 | 운영자 | 2020-03-25 22:42:00 |
+------+-----------------+----------------------+-----------+---------------------+
1 row in set (0.00 sec)
mysql>
입력이 잘 됐습니다. 그럼 URL로 요청시 컨트롤러가 이를 잘 받아 list.html을 화면에 출력해줄까요? 다시 localhost:8080/fileBoard/list로 접속합니다.
Insert(게시글 삽입) 작성
잘 출력되는 걸 보니 이상이 없는 것 같습니다. 하지만 글을 작성할 때 이렇게 terminal을 통해서 하는 것이 아니라 버튼을 눌러서 글을 작성해야하니, 작성한 컨트롤러를 따라 insert 페이지를 작성하겠습니다. 위에서 작성한 코드에서 '글작성' 버튼을 눌렀을 때 이동하는 URL을 onclick="location.href='/fileBoard/insert'" 로 입력했습니다. 이전에 작성한 컨트롤러와 동일하게 작성한 것이죠. 그래야 요청을 받아 작업을 수행할테니.
@RequestMapping("/insert")
private String fileBoardInsertForm(@ModelAttribute FileBoardVO board) {
return "fileBoard/insert";
}
insert.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>파일게시판 - 글작성</title>
</head>
<body>
<div>
<div style="padding: 10px; text-align: center;">
<h1><a th:href="@{/fileBoard/list}" style="text-decoration: none;">게시글작성</a></h1>
</div>
<div>
<form role="form" th:object=${fileBoardVO} th:action="@{/fileBoard/insertProc}"
method="post" enctype="multipart/form-data">
<div>
<label for="title" style="font-weight: bolder;">제목</label>
<input type="text" th:field="*{title}" id="title" name="title"
placeholder="제목을 입력하세요" required="required">
</div>
<div>
<label for="writer" style="font-weight: bolder;">작성자</label>
<input type="text" th:field="*{writer}" id="writer" name="writer"
placeholder="작성자를 입력하세요" required="required">
</div>
<div style="font-weight: bolder;">
<label for="content">내용</label><br/>
<textarea th:field="*{content}" id="content" name="content" rows="15" cols="50"
placeholder="내용을 입력하세요" required="required"></textarea>
</div>
<div>
<input type="file" name="files">
</div>
<div style="text-align: right;">
<input type="submit" th:value="목록" th:formaction="@{/fileBoard/list}">
<input type="submit" th:value="작성">
<input type="reset" th:value="취소">
</div>
</form>
</div>
<br/><br/><br/>
</div>
</body>
</html>
여기까지 잘 작성하셨나요? list페이지에서 '글작성' 버튼을 눌러보세요. 이상이 없다면 아래 사진과 같은 화면이 출력됩니다.
'목록' 버튼을 누르면 제목, 작성자, 내용의 required 속성 때문에 작동되지 않습니다. 이 항목들을 작성해야 list 페이지로 갑니다. required 속성을 삭제해도 됩니다. 취소버튼을 누르면 작성 내용이 삭제됩니다. 글을 작성했다면 '작성'버튼을 누르면 됩니다. 하지만 '작성'버튼을 누르면 이 버튼은 form 속성에 의해 <form ... th:action="@{/fileBoard/insertProc}" 로 이동하도록 했습니다. form속성에서 FileBoardVO 객체로 받은 데이터들을 Database로 전송해주는 과정을 거치는 작업이 필요하기 때문입니다. 그래서 지난번에 컨트롤러에 다음과 같이 작성했습니다.
@RequestMapping("/insertProc")
private String fileBoardInsertProc(@ModelAttribute FileBoardVO board, HttpServletRequest request) {
fboardService.fileBoardInsert(board);
return "forward:/fileBoard/list"; //객체 재사용
}
이처럼 컨트롤러에서 게시글에서 작성한 정보를 Database에 삽입하고 다시 forward로 list페이지로 이동하도록 작성했습니다. 이제 list페이지에서 버튼을 눌러 글을 작성해볼까요?
잘 되네요. 이번 글은 여기까지 작성하겠습니다. 다음에는 Update와 Delete를 작성하겠습니다. 다음 글에서 만나요! 제발~
댓글