앞서 작성한 Spring으로 만드는 간단한 게시판 만들기(1) (로그인)을 만들고 실제로 게시판을 구현할것이다.
게시판의 세부 기능은 C(Create),R(Read),U(Update),D(Delete)로 나눌수 있다.
기능을 구현하기에 앞서 일전에 언급했었던 것을 생성해야한다.
Board
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
|
package com.jeongmin.music.Board;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "board")
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String content;
private String title;
private String writer;
private Date date;
public Long getId() {
return id;
}
public String getContent() {
return content;
}
public String getTitle() {
return title;
}
public String getWriter() {
return writer;
}
public Date getDate() {
return date;
}
public void setId(Long id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setWriter(String writer) {
this.writer = writer;
}
public void setContent(String content) {
this.content = content;
}
public void setDate(Date date) {
this.date = date;
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
BoardRepository
1
2
3
4
5
6
7
8
9
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Repository;
@Repository
public interface BoardRepository extends JpaRepository<Board,Long> {
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
BoardController
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
70
71
72
73
74
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Controller;
import java.text.SimpleDateFormat;
import java.util.Map;
@Controller
public class BoardController {
private final BoardListService listService;
private final BoardWriteService boardWriteService;
private final BoardInfoService boardInfoService;
private final BoardDeleteService boardDeleteService;
private final BoardUpdateService boardUpdateService;
public BoardController(BoardListService listService, BoardWriteService boardWriteService,BoardInfoService boardInfoService,BoardDeleteService boardDeleteService,BoardUpdateService boardUpdateService)
{
this.listService=listService;
this.boardWriteService=boardWriteService;
this.boardInfoService=boardInfoService;
this.boardDeleteService=boardDeleteService;
this.boardUpdateService=boardUpdateService;
}
@GetMapping(value="/board")
public String listShow(@RequestParam(value="pageNum",defaultValue = "1")int pageNum){
listService.boardList(pageNum);
return "board";
}
@PostMapping(value = "/boardWriteRequest")
public String writeRequest(@RequestParam Map<String,String> paraMap)
{
return "redirect:/board"; //board로 바로가서 출력값 보여준다
}
@GetMapping(value="/Info")
public String getInfo(@RequestParam(value = "freeId")long freeId)
{
boardInfoService.InfoService(freeId);
return "boardInfo";
}
@GetMapping(value="/boardDelete")
public String getDelete(@RequestParam(value = "freeId") long freeId)
{
boardDeleteService.deleteService(freeId);
return "redirect:/board";
}
@GetMapping(value="/boardUpdate")
public String getUpdate(@RequestParam(value="freeId") long freeId)
{
boardInfoService.InfoService(freeId);
return "boardUpdate";
}
@PostMapping(value="/update")
public String update(@RequestParam Map<String,String> paraMap)
{
return "boardInfo";
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
PageMaker --> 게시판의 페이지
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
package com.jeongmin.music.Board;
public class PageMaker {
private int totalCount;// 전체 게시물 개수
private int pageNum=1;// 현재 페이지 번호
private int contentNum = 10;// 한 페이지에 몇 개 표시할지
private int startPage = 1;// 현재 페이지 블록의 시작페이지
private int endPage = 5;// 현재 페이지 블록의 마지막 페이지
private boolean prev = false;// 이전 페이지로 가는 화살표
private boolean next;// 다음 페이지로 가는 화살표
private int currentBlock;// 현재 페이지 블록
private int lastblock;// 마지막 페이지 블록
public void prevNext(int pageNum) {
if (pageNum > 0 && pageNum < 6) {
setPrev(false);
setNext(true);
}
else if (getLastblock() == getCurrentBlock()) {
setPrev(true);
setNext(false);
}
else {
setPrev(true);
setNext(true);
}
}
public int calcpage(int totalCount , int contentNum) {
int totalPage = totalCount / contentNum;
if (totalCount % contentNum > 0) {
totalPage++;
}
return totalPage;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getContentNum() {
return contentNum;
}
public void setContentNum(int contentNum) {
this.contentNum = contentNum;
}
public int getStartPage() {
return startPage;
}
public void setStartPage(int currentBlock) {
this.startPage = (currentBlock * 5) - 4;
//1 2 3 4 5
//6 7 8 9 10
//11 12 13
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int getLastBlock, int getCurrentBlock) {
if (getLastBlock == getCurrentBlock) { // 현재 페이지 블록이 마지막 블록이면
this.endPage = calcpage(getTotalCount(), getContentNum()); // 페이지 개수를 끝페이지로 지정
}
else {
this.endPage = getStartPage() + 4; // 시작 페이지 + 4를 끝페이지로 지정
}
}
public boolean isPrev() {
return prev;
}
public void setPrev(boolean prev) {
this.prev = prev;
}
public boolean isNext() {
return next;
}
public void setNext(boolean next) {
this.next = next;
}
public int getCurrentBlock() {
return currentBlock;
}
public void setCurrentBlock(int pageNum) { // 페이지 번호 5 들어옴
//페이지 번호를 통해서 구한다.
//페이지 번호 / 페이지 그룹 안의 개수
//1p 1 / 5 => 0.2
//5p 5 / 5 = > 1 -> 나머지는 0
this.currentBlock = pageNum / <span style="
|
다음으로는 C,R,U,D Service이다.
첫번째로는 ListService이다 게시글을 저장하면 데이터베이스에서 게시글 리스틀을 전부 가져오는 역활을 한다. 하지만 여기서 주의해야 할점은 첫번째 만들었을 때 게시글의 갯수가 0이니깐 분류를 해야한다. 나는 if(freeboardPage.getsize()==0)일때와 그렇지 않을때 2가지로 나누었다.
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
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class BoardListService {
public final HttpSession session;
public final BoardRepository boardRepository;
public final PageMakerService pageMakerService;
public BoardListService(HttpSession session,BoardRepository boardRepository, PageMakerService pageMakerService)
{
this.session=session;
this.boardRepository=boardRepository;
this.pageMakerService=pageMakerService;
}
public String boardList(int pageNum)
{
PageMaker pageMaker = pageMakerService.generatePageMaker(pageNum,10,boardRepository);
Page<Board> freeboardPage = boardRepository.findAll(pageRequest);
if(freeboardPage.getSize()==0)
{
session.setAttribute("boardList",new ArrayList<Board>());
session.setAttribute("pageMaker",pageMaker);
return "board";
}
List<Board> freeboardList = freeboardPage.getContent();
session.setAttribute("boardList",freeboardList);
session.setAttribute("pageMaker",pageMaker);
return "board";
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
두번째로는 Create부분이다.
Front에서 받아온 값을 객체 생성 및 값을 set해주고 해당되는 객체를 Repository에 save()를 해주고 session set을 해준다.
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
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Service;
@Service
public class BoardWriteService {
private final BoardRepository boardRepository;
private final HttpSession httpSession;
public BoardWriteService(BoardRepository boardRepository,HttpSession httpSession)
{
this.boardRepository=boardRepository;
this.httpSession=httpSession;
}
public void write(String title, String content, String writer)
{
Board board = new Board();
board.setTitle(title);
board.setContent(content);
board.setWriter(writer);
httpSession.setAttribute("board",board);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
세번째로는 Read부분이다.
나는 게시글에서 게시글의 재목을 클릭을 하였을 때 제목, 작성자, 내용 이렇게 3가지를 보이게 하였다.
해당되는 Id값을 가지고 Reposiroty에서 검색한다음 이것을 객체로 받아 session을 set해주면 front에서 session.board.getTitle()이렇게 하면 우리가 작성한 제목을 볼 수 있다.
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
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Service;
@Service
public class BoardInfoService {
private final BoardRepository boardRepository;
private final HttpSession session;
public BoardInfoService(BoardRepository boardRepository, HttpSession session)
{
this.boardRepository=boardRepository;
this.session= session;
}
public void InfoService(long freeId)
{
Board board = boardRepository.findById(freeId).get();
session.setAttribute("board",board);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
네번째로는 Delete부분이다. 해당되는 Id를 가지고 Repository에서 deleteById를 해주면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Service;
@Service
public class BoardDeleteService {
private final BoardRepository boardRepository;
public BoardDeleteService(BoardRepository boardRepository)
{
this.boardRepository=boardRepository;
}
public void deleteService(long freeId)
{
boardRepository.deleteById(freeId);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
마지막으로 Update부분이다. update는 처음에 생각하기 어려웠으나 Read+Create라는것을 알 수있었다. 이유는 게시글을 수정하기 위해서는 이전에 값을 알아야하고 또 이값을 다시 create하는것이기 때문이다.(그렇다고 코드상에 객체를 따로 생성하지는 않았다.)
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
|
package com.jeongmin.music.Board;
import org.springframework.stereotype.Service;
@Service
public class BoardUpdateService {
private final HttpSession session;
private final BoardRepository boardRepository;
public BoardUpdateService(HttpSession session, BoardRepository boardRepository)
{
this.session=session;
this.boardRepository= boardRepository;
}
public void Update(long id,String title,String content)
{
Board board= boardRepository.findById(id).get();//여기에서 findById가 optional이기 때문에 .get()을 사용해야 한다.
board.setTitle(title);
board.setContent(content);
session.setAttribute("board",board);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
Front
Board.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
|
<!DOCTYPE html>
th:with="lang=${#locale.language}" th:lang="${lang}">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<style>
table{
width: 100%;
border-top: 1px solid #444444;
border-collapse: collapse;
}
th, td{
border-bottom: 1px solid #444444;
padding: 10px;
}
</style>
<script>
function page(pageNum){
location.href="/board?pageNum="+pageNum;
}
function getPost(freeid) {
location.href="/Info?freeId="+freeid;
}
</script>
</head>
<body>
<div class="container">
<h3> Board</h3>
<div class="col-sm-8 text-left">
<table>
<thead>
<tr>
<th> 글 번호 </th>
<th> 글 제목 </th>
<th> 작성자 </th>
</tr>
<th:block th:if="${session.boardList!=null}">
<th:block th:each="board:${session.boardList}">
<tr>
<td><a th:onclick="|javascript:getPost('${board.getId()}')|" th:text="${board.getTitle()}"></a></td>
<td><span th:text="${board.getWriter()}"></span></td>
</tr>
</th:block>
</th:block>
</thead>
</table>
<!-- <a th:if="${session.pageMaker.isPrev()}" style="text-decoration: none;" th:onclick="|javascript:page('${session.pageMaker.getStartPage()}')|">«</a>-->
<!-- <th:block th:each="pageNum:${#numbers.sequence(session.pageMaker.getStartPage(),session.pageMaker.getEndPage())}">-->
<!-- <a th:text="${pageNum}" th:onclick="|javascript:page('${pageNum}')|"></a> -->
<!-- </th:block>-->
<!-- <a th:if="${session.pageMaker.isNext()}" style="text-decoration: none;" th:onclick="|javascript:page('${session.pageMaker.getEndPage()}')|">»</a>-->
</div>
</div>
<div class="col-sm-8 text-right">
<button type="button" style="color: white; background-color: gray; border-radius: 0.5em" onclick="location.href='/boardWrite'">글쓰기</button>
</div>
</body>
</html>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
BoardInfo.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
|
<!DOCTYPE html>
th:with="lang=${#locale.language}" th:lang="${lang}">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<style>
th,td{
padding:50px;
}
</style>
<script>
function page(pageNum){
location.href="/board?pageNum="+pageNum;
}
function getDelete(freeid) {
location.href = "/boardDelete?freeId=" + freeid;
}
function getUpdate(freeid){
location.href = "/boardUpdate?freeId=" +freeid;
}
</script>
</head>
<body>
<div class ="container-fluid text-center">
<span style="font-size: 20px">제목</span> <textarea style="height: 20px;" th:text="${session.board.getTitle()}" readonly="readonly"></textarea>
<br>
<span style="font-size: 20px">작성자</span> <textarea style="height: 20px" th:text="${session.board.getWriter()}" readonly="readonly"></textarea>
<br><br>
<textarea style="height: 100px;width: 100px;" th:text="${session.board.getContent()}" readonly="readonly"></textarea>
</div>
<div class="col-sm-8 text-right">
<button type="button" style="color: white; background-color: gray; border-radius: 0.5em" th:onclick="|javascript:getUpdate('${session.board.getId()}')|">수정</button>
</div>
<div class="col-sm-8 text-right">
<button type="button" style="color: white; background-color: gray; border-radius: 0.5em" th:onclick="|javascript:getDelete('${session.board.getId()}')|">삭제</button>
</div>
</body>
</html>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
BoardWrite.html (Create 부분)
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
|
<!DOCTYPE html>
th:with="lang=${#locale.language}" th:lang="${lang}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<body>
<div class="w3-container">
<h3>주의!</h3>
<div class="w3-panel w3-red">
<p style="">욕, 심한말, 법적신고가능함!</p>
</div>
</div>
<form action="/boardWriteRequest" method="post">
<input type="text" placeholder="글 제목" name="title">
<br><br>
<textarea placeholder="글 내용" name="content"></textarea>
<br><br>
<div class="button">
<button type="submit">Submit</button>
</div>
</form>
</body>
</html>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
BoardUpdate.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
|
<!DOCTYPE html>
th:with="lang=${#locale.language}" th:lang="${lang}">
<title>글 수정페이지</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<body>
<div class="w3-container">
<h3>주의!</h3>
<div class="w3-panel w3-red">
<p style="">욕, 심한말, 법적신고가능함!</p>
</div>
</div>
<form action="/update" method="post">
<br><br>
<input style="height:300px;width: 300px " th:value="${session.board.getContent()}" name="content"></input>
<br><br>
<div class="button">
<button type="submit">Submit</button>
</div>
</form>
</body>
</html>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
처음 Spring을 배우는데 많은 어려움이 있었지만 하나하나 해결해 나가는데 매우 재미있었던것 같다.
이번주 부터는 이 게시판과는 별개로 따로 만든 게시판을 서버에 올렸는데 그 과정을 Posting할 예정이고 그 게시판을 Refactoring 및 Restful하게 만들 계획이다. (이 게시판은 Service Flow를 확실히 이해하기 위해 다시 처음부터 만들었던 코드이다,)
Service Flow를 이해하기 위한 나의 그림
'SpringBoot' 카테고리의 다른 글
Homebrew 설치 및 gradle설치 (0) | 2019.07.23 |
---|---|
사용중인 포트 찾아서 Kill하기 (0) | 2019.07.23 |
Spring으로 만드는 간단한 게시판(1) (0) | 2019.07.22 |
Get & Post (0) | 2019.07.08 |
해시(Hash) 와 암호화(Encryption) (0) | 2019.07.08 |