1. boardPackage
1. BoardController
@GetMapping("/v2/api/board/{id}/update-form")
public @ResponseBody BoardResponse.DTO updateForm(@PathVariable("id") int id) {
User sessionUser = (User) session.getAttribute("sessionUser");
BoardResponse.DTO model = boardService.게시글수정화면V2(id, sessionUser);
return model;
}
- 코드 설명
주어진 코드는 Spring Boot 애플리케이션에서 사용되는 RESTful API 엔드포인트입니다. 이 메소드는 특정 게시글의 수정 화면 데이터를 제공하는 역할을 합니다.
@GetMapping("/v2/api/board/{id}/update-form")
:- 이 어노테이션은 HTTP GET 요청을 처리하는 메소드를 정의합니다.
"/v2/api/board/{id}/update-form"
경로는 클라이언트가 특정 게시글의 수정 폼 데이터를 요청할 때 사용됩니다.{id}
는 URL 경로 변수로, 수정하려는 게시글의 ID를 나타냅니다.
@ResponseBody
:- 이 어노테이션은 메소드의 리턴 값이 HTTP 응답 본문으로 직렬화되어 전송됨을 나타냅니다.
- 따라서
BoardResponse.DTO
객체는 JSON 형식으로 변환되어 클라이언트에게 응답됩니다.
@PathVariable("id") int id
:@PathVariable
어노테이션은 URL 경로에 포함된 변수를 메소드 매개변수로 매핑합니다.- 여기서는
{id}
경로 변수를int id
로 받아 사용합니다.
User sessionUser = (User) session.getAttribute("sessionUser");
:- 이 코드는 현재 세션에서
sessionUser
라는 이름으로 저장된User
객체를 가져옵니다. - 이 객체는 현재 로그인한 사용자의 정보를 담고 있을 것입니다.
BoardResponse.DTO model = boardService.게시글수정화면V2(id, sessionUser);
:boardService.게시글수정화면V2
메소드를 호출하여 게시글의 수정 화면에 필요한 데이터를 가져옵니다.- 이 메소드에는 게시글의 ID(
id
)와 현재 세션 사용자(sessionUser
)가 인자로 전달됩니다. 게시글수정화면V2
메소드는 수정 화면에 필요한 데이터를 가공하거나 권한 검사를 수행할 수 있습니다.
return model;
:BoardResponse.DTO
객체를 클라이언트에게 반환합니다.- 이 객체는 게시글 수정 화면에 필요한 데이터를 포함하고 있을 것입니다.
요약
이 메소드는 특정 게시글의 수정 화면 데이터를 반환하는 역할을 합니다. 클라이언트는 이 데이터를 받아 수정 화면을 구성할 수 있습니다. 메소드는 현재 세션에서 사용자 정보를 가져와, 해당 사용자가 수정하려는 게시글에 접근할 수 있는지 검증하는 데 사용될 수 있습니다.
@GetMapping("/v2/board/{id}")
public @ResponseBody BoardResponse.DetailDTO detailV2(@PathVariable("id") Integer id){
User sessionUser = (User) session.getAttribute("sessionUser");
BoardResponse.DetailDTO model = boardService.게시글상세보기(sessionUser, id);
return model;
}
@GetMapping("/v3/board/{id}")
public @ResponseBody Board detailV3(@PathVariable("id") Integer id) {
User sessionUser = (User) session.getAttribute("sessionUser");
Board model = boardService.게시글상세보기V3(sessionUser, id);
return model;
}
- 코드설명
Board model = boardService.게시글상세보기V3(sessionUser, id);
:boardService.게시글상세보기V3
메소드를 호출하여 특정 게시글의 상세 정보를 가져옵니다.
- 이 메소드에는 게시글의 ID(
id
)와 현재 세션 사용자(sessionUser
)가 인자로 전달됩니다.
게시글상세보기V3
메소드는 상세 정보 조회 시 필요한 권한 검사를 수행하거나, 데이터를 가공하여 반환할 수 있습니다.
요약
이 메소드는 특정 게시글의 상세 정보를 조회하여 클라이언트에게 반환하는 역할을 합니다. 클라이언트는 이 데이터를 사용하여 게시글의 상세 화면을 구성할 수 있습니다. 또한, 현재 세션에서 사용자 정보를 가져와, 해당 사용자가 게시글에 접근할 수 있는지 검증하는 데 사용될 수 있습니다.
이 메소드는 사용자와의 세션 정보를 활용하여, 사용자 맞춤형 데이터를 제공하거나 보안 관리를 강화할 수 있는 구조를 가지고 있습니다.
2. BoardResponse
@Data
public static class DTO {
private Integer id;
private String title;
private String content;
public DTO(Board board) {
this.id = board.getId();
this.title = board.getTitle();
this.content = board.getContent();
}
}
- 코드설명
이 코드는
DTO
라는 데이터 전송 객체(Data Transfer Object)를 정의하는 것입니다. DTO
클래스는 특정 엔티티(여기서는 Board
클래스)의 필요한 일부 컬럼만 선택적으로 포함하기 위해 사용됩니다.간단한 설명
- 목적:
DTO
클래스는 클라이언트에게 전달할 데이터 중 필요한 컬럼만 선택하여 전송하기 위해 만들어졌습니다.
- 구성 요소:
id
,title
,content
필드를 가지고 있으며, 이는Board
엔티티의 일부 정보만 담고 있습니다.
- 생성자:
DTO(Board board)
생성자는Board
객체를 받아 필요한 필드(id
,title
,content
)만 초기화합니다.
이렇게 함으로써 클라이언트에 불필요한 정보를 보내지 않고, 필요한 데이터만 전달할 수 있게 됩니다.
@Data
public static class DetailDTO {
private Integer id;
private String title;
private String content;
private Boolean isOwner;
private String username;
//댓글들이 들어와야한다.
private List<ReplyDTO> replies = new ArrayList<>();
public DetailDTO(Board board, User sessionUser) {
this.id = board.getId();
this.title = board.getTitle();
this.content = board.getContent();
this.isOwner = false;
if (sessionUser != null) {
if (board.getUser().getId() == sessionUser.getId()) {
isOwner = true; // 권한체크
}
}
this.username = board.getUser().getUsername();
for (Reply reply : board.getReplies()) {
replies.add(new ReplyDTO(reply, sessionUser));
}
}
}
- 코드설명
주어진 코드는
DetailDTO
클래스의 생성자에서 게시글(Board
)의 댓글(Reply
)을 순회하며 ReplyDTO
객체로 변환해 replies
리스트에 추가하는 부분입니다. 이 부분에 대해 자세히 설명해드릴게요.코드 설명 (for 문 부분)
for (Reply reply : board.getReplies()) {
replies.add(new ReplyDTO(reply, sessionUser));
}
for
루프:- 이
for
문은board.getReplies()
메소드를 호출하여 가져온 댓글 리스트를 순회합니다. board.getReplies()
는 해당Board
객체에 연결된 모든Reply
객체(댓글)를 반환합니다.
Reply
객체 순회:Reply reply
는board.getReplies()
로부터 순차적으로 각 댓글 객체를 하나씩 가져옵니다.- 이 루프는
board
에 연결된 모든 댓글을 순회합니다.
replies.add(new ReplyDTO(reply, sessionUser));
:- 각
Reply
객체를ReplyDTO
로 변환합니다. new ReplyDTO(reply, sessionUser)
는 각 댓글Reply
객체와 현재 세션 사용자(sessionUser
) 정보를 이용해 새로운ReplyDTO
객체를 생성합니다.- 생성된
ReplyDTO
객체는replies
리스트에 추가됩니다.
ReplyDTO
생성자:ReplyDTO
는 댓글에 대한 정보를 담는 데이터 전송 객체입니다.ReplyDTO
생성자에reply
와sessionUser
를 넘겨줌으로써, 댓글의 내용과 현재 사용자와의 관계 등을 고려하여 DTO 객체를 생성하게 됩니다. 예를 들어, 사용자가 댓글의 작성자인지 여부를 판단하는 로직이 있을 수 있습니다.
요약
이
for
문은 특정 게시글에 달린 모든 댓글을 순회하며, 각 댓글을 ReplyDTO
객체로 변환하여 DetailDTO
객체의 replies
리스트에 추가하는 역할을 합니다. 이렇게 함으로써 클라이언트가 요청할 때마다 게시글과 함께 해당 게시글에 달린 모든 댓글 정보를 손쉽게 전달할 수 있습니다.이 과정에서 각 댓글의 세부 사항뿐만 아니라, 현재 세션 사용자가 댓글의 작성자인지 여부 등 추가적인 정보도
ReplyDTO
를 통해 담을 수 있습니다.@Data
public static class ReplyDTO{
private Integer id;
private String content;
private boolean isOwner;
private String username;
public ReplyDTO(Reply reply, User sesstionUser) {
this.id = reply.getId();
this.content = reply.getComment();
this.username = reply.getUser().getUsername();
this.isOwner = false;
if (sesstionUser != null) {
if (reply.getUser().getId() == sesstionUser.getId()) {
isOwner = true; //권한체크
}
}
- 코드설명
ReplyDTO
클래스는 댓글에 대한 정보를 담는 데이터 전송 객체(Data Transfer Object)로, 특정 댓글(Reply
)의 일부 정보를 선택적으로 담기 위해 사용됩니다.간단한 설명
- 필드:
id
,content
,isOwner
,username
필드가 있으며, 각각 댓글의 ID, 내용, 작성자 여부, 작성자 이름을 저장합니다.
- 생성자:
ReplyDTO(Reply reply, User sessionUser)
는Reply
객체와 현재 세션 사용자(sessionUser
)를 인자로 받아 필요한 정보를 초기화합니다. isOwner
: 현재 세션 사용자가 댓글 작성자인지 확인하여true
또는false
로 설정됩니다.
이 클래스는 클라이언트에게 필요한 댓글 정보만을 제공하기 위해 설계되었습니다.
isOwner
필드는 권한 체크를 위해 사용되어, 현재 사용자가 댓글을 작성했는지 여부를 나타냅니다.3. BoardService
public BoardResponse.DTO 게시글수정화면V2(int id, User sessionUser) {
Board board = boardRepository.findById(id)
.orElseThrow(()-> new Exception404("게시글을 찾을 수 없습니다"));
if (board.getUser().getId() != sessionUser.getId()) {
throw new Exception403("게시글 수정 권한이 없습니다.");
}
return new BoardResponse.DTO(board);
}
이 코드는 특정 게시글을 수정하기 위한 데이터를 준비하는 서비스 메소드입니다. 이 메소드는 게시글을 찾고, 현재 사용자에게 해당 게시글을 수정할 권한이 있는지 확인한 후, 권한이 있다면 해당 게시글의 정보를 담은 DTO 객체를 반환합니다.
Board board = boardRepository.findById(id)
:boardRepository.findById(id)
메소드를 호출하여 데이터베이스에서 해당 ID에 해당하는Board
(게시글) 객체를 찾습니다.Optional
로 반환된 결과를orElseThrow
를 통해 예외 처리하여, 해당 게시글이 존재하지 않을 경우Exception404
를 발생시킵니다.Exception404
: "게시글을 찾을 수 없습니다"라는 메시지를 가진 예외를 던지며, 이는 404 Not Found HTTP 상태 코드를 의미합니다.
if (board.getUser().getId() != sessionUser.getId())
:- 현재 세션 사용자(
sessionUser
)의 ID와 게시글 작성자의 ID를 비교합니다. - 만약 현재 사용자가 게시글 작성자가 아니라면, 게시글을 수정할 권한이 없다고 판단하여
Exception403
예외를 발생시킵니다. Exception403
: "게시글 수정 권한이 없습니다."라는 메시지를 가진 예외를 던지며, 이는 403 Forbidden HTTP 상태 코드를 의미합니다.
return new BoardResponse.DTO(board);
:- 권한 검사를 통과한 경우, 게시글의 정보를 담은
BoardResponse.DTO
객체를 생성하여 반환합니다. BoardResponse.DTO
는 게시글의 ID, 제목, 내용 등 필요한 정보를 담고 있는 데이터 전송 객체로, 클라이언트에 필요한 데이터만을 전송하기 위해 사용됩니다.
요약
이 메소드는 게시글 수정 화면을 준비하는 데 필요한 데이터를 가져오는 역할을 합니다.
- 먼저 게시글을 데이터베이스에서 조회하고,
- 현재 사용자가 해당 게시글을 수정할 권한이 있는지 확인한 후,
- 권한이 있다면 게시글 정보를 담은 DTO 객체를 반환합니다.
이를 통해 클라이언트가 수정할 게시글의 데이터를 안전하게 가져올 수 있도록 보장합니다.
public Board 게시글상세보기V3(User sessionUser, Integer boardId){
Board boardPS = boardRepository.mFindByIdWithReply(boardId)
.orElseThrow(() -> new Exception404("게시글이 없습니다."));
return boardPS;
}
- 코드설명
이 코드는 특정 게시글의 상세 정보를 조회하는 서비스 메소드입니다. 이 메소드는 게시글과 그에 대한 댓글까지 포함한 상세 정보를 가져오기 위해 사용됩니다. 이전에 설명한 코드와의 차이점도 포함하여 설명하겠습니다.
Board boardPS = boardRepository.mFindByIdWithReply(boardId)
:boardRepository.mFindByIdWithReply(boardId)
메소드는 데이터베이스에서 특정 ID의 게시글을 조회하며, 해당 게시글에 달린 댓글도 함께 가져옵니다.
- 이 메소드는 게시글과 관련된 모든 데이터를 한 번에 가져오는 방식입니다.
return boardPS;
:- 조회된 게시글 객체
boardPS
를 반환합니다.
- 이 객체에는 게시글의 내용뿐만 아니라, 게시글에 달린 모든 댓글 정보도 포함되어 있을 수 있습니다.
4. detail.mustach
{{>layout/header}}
<div class="container p-5">
<!-- 수정삭제버튼 -->
{{#model.isOwner}}
<div class="d-flex justify-content-end">
<a href="/api/board/{{model.id}}/update-form" class="btn btn-warning me-1">수정</a>
<form action="/api/board/{{model.id}}/delete" method="post">
<button class="btn btn-danger">삭제</button>
</form>
</div>
{{/model.isOwner}}
<div class="d-flex justify-content-end">
<!-- 컬렉션이면 user로 만들어야한다.-->
<b>작성자</b> : {{model.username}}
</div>
<!-- 게시글내용 -->
<div>
<h2><b>{{model.title}}</b></h2>
<hr/>
<div class="m-4 p-2">
{{{model.content}}}
</div>
</div>
<!-- 댓글 -->
<div class="card mt-3">
<!-- 댓글등록 -->
<div class="card-body">
<form action="/reply/save" method="post">
<textarea class="form-control" rows="2" name="comment"></textarea>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-outline-primary mt-1">댓글등록</button>
</div>
</form>
</div>
<!-- 댓글목록 -->
<div class="card-footer">
<b>댓글리스트</b>
</div>
<div class="list-group">
{{#model.replies}}
<!-- 댓글아이템 -->
<div class="list-group-item d-flex justify-content-between align-items-center">
<div class="d-flex">
<div class="px-1 me-1 bg-primary text-white rounded">{{username}}</div>
<div>{{comment}}</div>
</div>
{{#isOwner}}
<form action="#" method="post">
<button class="btn">🗑</button>
</form>
{{/isOwner}}
</div>
{{/model.replies}}
</div>
</div>
</div>
{{>layout/footer}}
- 코드설명
제공된 HTML 코드와 {{ }} 안의 Mustache 템플릿 구문은 서버에서 가져온 데이터와 동적으로 결합하여 클라이언트에 표시하는 방식입니다.
코드 설명 및 연관성
{{model.isOwner}}
:- 연관된 Java 코드:
DetailDTO
클래스의isOwner
필드. - 설명:
model.isOwner
는 현재 사용자가 해당 게시글의 소유자인지를 나타냅니다. 이 값은DetailDTO
생성자에서 설정됩니다. 만약 세션 사용자(sessionUser
)의 ID와 게시글 작성자의 ID가 같다면isOwner
는true
로 설정됩니다. - 적용: 이 부분은 사용자가 게시글의 작성자인 경우에만 "수정"과 "삭제" 버튼을 표시하도록 합니다.
{{model.username}}
:- 연관된 Java 코드:
DetailDTO
클래스의username
필드. - 설명:
model.username
은 게시글 작성자의 사용자 이름을 나타냅니다.DetailDTO
생성자에서board.getUser().getUsername()
을 통해 설정됩니다. - 적용: 이 값은 게시글 작성자의 이름을 표시하는 데 사용됩니다.
- *
{{model.title}}
*와{{{model.content}}}
: - 연관된 Java 코드:
DetailDTO
클래스의title
과content
필드. - 설명:
model.title
과model.content
는 게시글의 제목과 내용입니다.DetailDTO
생성자에서Board
객체의 제목과 내용으로 초기화됩니다. - 적용: 이 값들은 각각 게시글의 제목과 내용을 화면에 표시하는 데 사용됩니다.
{{#model.replies}} ... {{/model.replies}}
:- 연관된 Java 코드:
DetailDTO
클래스의replies
리스트. - 설명:
model.replies
는 게시글에 달린 댓글 목록을 나타냅니다.DetailDTO
생성자에서Board
객체의 댓글 목록을ReplyDTO
로 변환하여 저장합니다. - 적용: 이 부분은 댓글 목록을 반복하여 화면에 출력합니다. 각각의 댓글은
ReplyDTO
로부터username
과comment
정보를 가져와 표시합니다.
{{username}}
와{{comment}}
(댓글 부분):- 연관된 Java 코드:
ReplyDTO
클래스의username
과content
필드. - 설명: 댓글 작성자의 이름과 댓글 내용을 나타냅니다.
ReplyDTO
생성자에서Reply
객체의 데이터를 기반으로 초기화됩니다. - 적용: 각 댓글 항목에서 댓글 작성자의 이름과 댓글 내용이 표시됩니다.
{{#isOwner}} ... {{/isOwner}}
(댓글 삭제 버튼 부분):- 연관된 Java 코드:
ReplyDTO
클래스의isOwner
필드. - 설명:
isOwner
는 현재 세션 사용자가 해당 댓글의 작성자인지를 나타냅니다. 댓글 작성자와 세션 사용자의 ID가 같을 때true
로 설정됩니다. - 적용: 이 조건에 따라 현재 사용자가 댓글의 작성자인 경우에만 댓글 삭제 버튼이 나타납니다.
요약
이 HTML 템플릿은 Java에서 생성된 DTO 객체(
DetailDTO
, ReplyDTO
)의 데이터를 이용하여 동적으로 화면을 구성합니다. 각 템플릿 태그({{ }}
)는 Java 객체의 필드 값을 참조하여 화면에 필요한 정보를 표시하거나 특정 동작(예: 수정/삭제 버튼 표시)을 제어합니다. 이를 통해 서버와 클라이언트 간의 데이터 통신이 원활하게 이루어질 수 있습니다.Share article