11-회원제 게시판 만들기_SpringBoot와 JPA
04-게시판(board)파트 - SpringBoot
[게시판-글 상세조회]
[첫번재-새창을 띄워 글상세조회 화면 보여주기]
findAll.html에 글상세조회 링크(/board/findById)를 추가한다.
단 글상세조회는 글제목을 클릭 시 글상세조회 페이지로 이동하게 하고
로그인 여부와 관계없이 보이도록 한다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글목록</title>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
</head>
<body>
<div th:align="center">
<h2>글 목록</h2>
<table>
<thead>
<tr>
<!-- <th>회원번호</th>-->
<th>글번호</th>
<th>작성자명</th>
<!-- <th>비밀번호</th>-->
<th>제목</th>
<th>조회수</th>
<th>작성일자</th>
<th>회원번호</th>
<th>글 상세조회</th>
</tr>
</thead>
<tbody>
<tr th:each="board: ${boardList}">
<td th:text="${board.boardId}"></td>
<td th:text="${board.boardWriter}"></td>
<td><a th:href="@{|/board/${board.boardId}|}">
<span th:text="${board.boardTitle}"></span></a></td>
<td th:text="${board.boardHits}"></td>
<td th:text="${board.boardDate}"></td>
<td th:text="${board.memberId}"></td>
</tr>
</tbody><br><br>
</table>
</div>
</body>
</html>
resources/board 폴더에 findById.html로 글상세화면을 아래와 같이 보이는 형식으로 만든다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
</head>
<body>
<h2>상세글</h2>
<table>
<thead>
<tr>
<td>번호</td>
<td>제목</td>
<td>작성자</td>
<td>내용</td>
<!-- <td>프로필 사진</td>-->
<td>조회수</td>
<td>작성일자</td>
</tr>
</thead>
<tbody>
<tr>
<td th:text="${board.boardId}"></td>
<td th:text="${board.boardTitle}"></td>
<td th:text="${board.boardWriter}"></td>
<td th:text="${board.boardContents}"></td>
<!-- <td><img th:src="@{/boardImg/}+${board.boardFilename}" alt="프로필사진"></td>-->
<td th:text="${board.boardHits}"> </td>
<td th:text="${board.boardDate}"></td>
</tr>
</tbody>
</table>
<br>
</body>
</html>
BoardController에 글상세화면을 보여주기 위한 메서드(findAll)를 작성한다.
주소형식은 "board/글번호"으로 작성해준다.
// 글 상세화면
@GetMapping("/{boardId}")
public String findById(@PathVariable("boardId") Long boardId, Model model, HttpSession session) {
BoardDetailDTO boardDetailDTO = bs.findById(boardId);
bs.hits(boardId);
model.addAttribute("board", boardDetailDTO);
return "/board/findById";
}
BoardController 內 bs.findById(boardId)을 클릭하면 BoardService에 내용이 자동으로 추가된다.
// 글 상세화면
BoardDetailDTO findById(Long boardId);
BoardServiceImpl에 관련 내용을 추가한다.
// 글 상세화면 보여주기
@Override
public BoardDetailDTO findById(Long boardId) {
BoardDetailDTO board = BoardDetailDTO.toBoardDetailDTO(br.findById(boardId).get());
return board;
}
BoardDetailDTO에 toBoardDetailDTO에 대한 내용을 추가해준다.
package com.ex.test01.dto;
import com.ex.test01.entity.BoardEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Date;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BoardDetailDTO {
private Long boardId;
private Long memberId;
private String boardWriter;
private String boardTitle;
private String boardContents;
private String boardFilename;
private LocalDateTime boardDate;
private int boardHits;
public static BoardDetailDTO toBoardDetailDTO(BoardEntity boardEntity) {
BoardDetailDTO boardDetailDTO = new BoardDetailDTO();
boardDetailDTO.setBoardId(boardEntity.getBoardId());
boardDetailDTO.setBoardWriter(boardEntity.getBoardWriter());
boardDetailDTO.setBoardTitle(boardEntity.getBoardTitle());
boardDetailDTO.setBoardContents(boardEntity.getBoardContents());
boardDetailDTO.setBoardFilename(boardEntity.getBoardFilename());
if (boardEntity.getUpdateTime()==null) {
boardDetailDTO.setBoardDate(boardEntity.getCreateTime());
} else {
boardDetailDTO.setBoardDate(boardEntity.getUpdateTime());
}
boardDetailDTO.setBoardHits(boardEntity.getBoardHits());
boardDetailDTO.setMemberId(boardEntity.getBoardId());
return boardDetailDTO;
}
}
여기까지 작성 후 글목록 화면에서 글제목을 눌러 기작성되어 있던 글의 상세화면이 정상적으로 보여지는지 확인한다.
상기와 같이 글 상세내용이 정상적으로 보여진다면
새로운 페이지를 띄워 글상세화면을 보여주는 기능구현은 완료되었다.
[두번째-Ajax를 이용하여 글목록 하단에 글상세조회 화면 보여주기]
findAll.html에 글상세조회 버튼을(/board/findById)를 추가한다.
단 글상세조회는 글상세조회 버튼을 클릭 시 글목록 하단에 글의 상세정보가 나타나며
로그인 여부와 관계없이 보이도록 한다.
주소형식은 "board/글번호"로 상단의 구현방식과 동일하다.
아래의 이미지를 참고하자.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글목록</title>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script>
// function detail(boardId){
const detail = (boardId) => {
console.log(boardId);
const reqUrl = "/board/" + boardId;
$.ajax({
type: 'post',
url: reqUrl,
dataType: 'json',
success: function(result) {
console.log(result);
let output = "";
output += "<table>\n" +
" <thead>\n" +
" <tr>\n" +
" <th>글번호</th>\n" +
" <th>작성자명</th>\n" +
" <th>제목</th>\n" +
" <th>조회수</th>\n" +
" <th>작성일자</th>\n" +
" <th>회원번호</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody>\n" +
" <tr>\n" +
" <td>"+result.boardId + "</td>\n" +
" <td>"+result.boardWriter + "</td>\n" +
" <td>"+result.boardTitle+ "</td>\n" +
" <td>"+result.boardHits+ "</td>\n" +
" <td>"+result.boardDate + " </td>\n" +
" <td>"+result.memberId + " </td>\n" +
" </tr>\n" +
" </tbody>\n" +
"</table>"
document.getElementById("board-detail").innerHTML = output;
},
error: function() {
alert('ajax 실패');
}
});
}
</script>
</head>
<body>
<div th:align="center">
<h2>글 목록</h2>
<table>
<thead>
<tr>
<!-- <th>회원번호</th>-->
<th>글번호</th>
<th>작성자명</th>
<!-- <th>비밀번호</th>-->
<th>제목</th>
<th>조회수</th>
<th>작성일자</th>
<th>회원번호</th>
<th>글 상세조회</th>
</tr>
</thead>
<tbody>
<tr th:each="board: ${boardList}">
<td th:text="${board.boardId}"></td>
<td th:text="${board.boardWriter}"></td>
<td><a th:href="@{|/board/${board.boardId}|}">
<span th:text="${board.boardTitle}"></span></a></td>
<td th:text="${board.boardHits}"></td>
<td th:text="${board.boardDate}"></td>
<td th:text="${board.memberId}"></td>
<td><button th:onclick="detail([[${board.boardId}]])">글 상세조회(Ajax)</button></td>
</tr>
</tbody><br><br>
</table>
<br><br><br>
<div id="board-detail"></div>
</div>
</body>
</html>
BoardController에 Ajax로 글상세내용을 보여주는 메서드를 추가한다.
// Ajax를 이용하여 글 상세화면을 글목록 하단에 보여주기
@PostMapping("/{boardId}")
public @ResponseBody BoardDetailDTO detail(@PathVariable Long boardId) {
BoardDetailDTO board = bs.findById(boardId);
return board;
}
이 이후부터는 상단에 썼던 "새창을 띄워 글상세정보 보기"의 BoardService, BoardServiceImpl
그리고 BoardEntity와 동일하기에 추가로 작성할 필요가 없다.
다만 이해를 위해 상단의 내용을 다시 한번 써본다..
BoardService
// 글 상세화면
BoardDetailDTO findById(Long boardId);
BoardServiceImpl
// 글 상세화면 보여주기
@Override
public BoardDetailDTO findById(Long boardId) {
BoardDetailDTO board = BoardDetailDTO.toBoardDetailDTO(br.findById(boardId).get());
return board;
}
BoardEntity
package com.ex.test01.dto;
import com.ex.test01.entity.BoardEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Date;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BoardDetailDTO {
private Long boardId;
private Long memberId;
private String boardWriter;
private String boardTitle;
private String boardContents;
private String boardFilename;
private LocalDateTime boardDate;
private int boardHits;
public static BoardDetailDTO toBoardDetailDTO(BoardEntity boardEntity) {
BoardDetailDTO boardDetailDTO = new BoardDetailDTO();
boardDetailDTO.setBoardId(boardEntity.getBoardId());
boardDetailDTO.setBoardWriter(boardEntity.getBoardWriter());
boardDetailDTO.setBoardTitle(boardEntity.getBoardTitle());
boardDetailDTO.setBoardContents(boardEntity.getBoardContents());
boardDetailDTO.setBoardFilename(boardEntity.getBoardFilename());
if (boardEntity.getUpdateTime()==null) {
boardDetailDTO.setBoardDate(boardEntity.getCreateTime());
} else {
boardDetailDTO.setBoardDate(boardEntity.getUpdateTime());
}
boardDetailDTO.setBoardHits(boardEntity.getBoardHits());
boardDetailDTO.setMemberId(boardEntity.getBoardId());
return boardDetailDTO;
}
}
댓글남기기