35. 글상세보기v5

송민경's avatar
Mar 18, 2024
35. 글상세보기v5

1. BoardService 에 detail() 만들기

  • board와 isOwner를 응답해야하나 method는 하나밖에 응답할 수 없음
  • DTO를 만들어서 하나의 덩어리로 만들어서 줘야 함
package shop.mtcoding.blog.board; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import shop.mtcoding.blog._core.errors.exception.Exception403; import shop.mtcoding.blog._core.errors.exception.Exception404; import shop.mtcoding.blog.user.User; import java.util.List; @RequiredArgsConstructor @Service public class BoardService { private final BoardJPARepository boardJPARepository; // board와 isOwner를 응답해야하나 method는 하나밖에 응답할 수 없음 -> 하나의 덩어리로 만들어서 줘야 함 public Board detail(Integer boardId, User sessionUser) { Board board = boardJPARepository.findByIdJoinUser(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); // 로그인을 하고, 게시글의 주인이면 isOwner가 true가 된다. boolean isOwner = false; if(sessionUser != null){ if(sessionUser.getId() == board.getUser().getId()){ isOwner = true; } } return board; } public List<Board> findAll() { Sort sort = Sort.by(Sort.Direction.DESC,"id"); return boardJPARepository.findAll(sort); } @Transactional public void delete(int boardId, Integer sessionUserId) { Board board = boardJPARepository.findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); if (sessionUserId != board.getUser().getId()) { throw new Exception403("게시글을 삭제할 권한이 없습니다"); } boardJPARepository.deleteById(boardId); } public void update(int boardId, int sessionUserId, BoardRequest.UpdateDTO reqDTO) { Board board = boardJPARepository.findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); board.setTitle(reqDTO.getTitle()); board.setContent(reqDTO.getContent()); } public Board updateForm (int boardId, int sessionUserId) { // 1. 조회 및 예외처리 Board board = boardJPARepository.findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); // 2. 권한 처리 if (sessionUserId != board.getUser().getId()) { throw new Exception403("게시글 수정페이지로 이동할 권한이 없습니다"); } return board; } @Transactional public void save(BoardRequest.SaveDTO reqDTO, User sessionUser) { boardJPARepository.save(reqDTO.toEntity(sessionUser)); } }
 

2. BoardResponse 만들어서 DetailDTO 만들기

  • UserDTO 만들어서 isOwner 추가하기
  • isOwner에 대한 if 분기하기
package shop.mtcoding.blog.board; import lombok.Data; import shop.mtcoding.blog.user.User; public class BoardResponse { @Data public static class DetailDTO { private Integer id; private String title; private String content; private UserDTO user; private Boolean isOwner; public DetailDTO(Board board, User sessionUser) { this.id = board.getId(); this.title = board.getTitle(); this.content = board.getContent(); this.user = new UserDTO(board.getUser()); this.isOwner = false; if(sessionUser != null){ if(sessionUser.getId() == board.getUser().getId()){ isOwner = true; } } } @Data public class UserDTO { private int id; private String username; public UserDTO(User user) { this.id = user.getId(); this.username = user.getUsername(); } } } }
 

3. DTO없이 isOwner 만들기

  • Board 에 @Transient 걸어서 isOwner만들기 → 테이블에 생성이 안 됨
  • JsonIncludeProperties({","}) : 해당 속성 제외하기
  • @JsonIgnore : 표시 안하기
  • SSL은 화면에 이상한 데이터가 날아갈 일이 없음
    • notion image
package shop.mtcoding.blog.board; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIncludeProperties; import jakarta.persistence.*; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; import shop.mtcoding.blog.user.User; import shop.mtcoding.blog._core.utils.MyDateUtil; import java.sql.Timestamp; @NoArgsConstructor @Data // 변경되는 데이터에만 setter가 필요함 @Table(name = "board_tb") @Entity public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String title; private String content; // private String username; // username은 user_tb에도 있기에 외래키로 연관관계 맺어야 함 // @JoinColumn(name = "user_id") 직접 지정할 때 @JsonIncludeProperties({"password, email, createdAt"}) // 해당 속성 제외하기 @ManyToOne(fetch = FetchType.LAZY) // ORM 할 것이기에 user 객체 필요 private User user; // DB에 컬럼명 : user_id (변수명_PK키) @JsonIgnore // 표시 안하기 @CreationTimestamp // PC로 인해 DB에 INSERT될 때 날짜 주입 private Timestamp createdAt; @Transient // 테이블 생성이 안됨 private boolean isOwner; public void update(){ } @Builder public Board(Integer id, String title, String content, User user, Timestamp createdAt) { this.id = id; this.title = title; this.content = content; this.user = user; this.createdAt = createdAt; } public String getBoardDate(){ return MyDateUtil.timestampFormat(createdAt); } }
notion image
 

4. BoardService 에 detail 수정하기

package shop.mtcoding.blog.board; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import shop.mtcoding.blog._core.errors.exception.Exception403; import shop.mtcoding.blog._core.errors.exception.Exception404; import shop.mtcoding.blog.user.User; import java.util.List; @RequiredArgsConstructor @Service public class BoardService { private final BoardJPARepository boardJPARepository; // board와 isOwner를 응답해야하나 method는 하나밖에 응답할 수 없음 -> 하나의 덩어리로 만들어서 줘야 함 public Board detail(int boardId, User sessionUser) { Board board = boardJPARepository.findByIdJoinUser(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); boolean isOwner = false; if(sessionUser != null){ if(sessionUser.getId() == board.getUser().getId()){ isOwner = true; } } board.setOwner(isOwner); return board; } public List<Board> findAll() { Sort sort = Sort.by(Sort.Direction.DESC, "id"); return boardJPARepository.findAll(sort); } @Transactional public void delete(int boardId, Integer sessionUserId) { Board board = boardJPARepository.findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); if (sessionUserId != board.getUser().getId()) { throw new Exception403("게시글을 삭제할 권한이 없습니다"); } boardJPARepository.deleteById(boardId); } public void update(int boardId, int sessionUserId, BoardRequest.UpdateDTO reqDTO) { Board board = boardJPARepository.findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); board.setTitle(reqDTO.getTitle()); board.setContent(reqDTO.getContent()); } public Board updateForm(int boardId, int sessionUserId) { // 1. 조회 및 예외처리 Board board = boardJPARepository.findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다")); // 2. 권한 처리 if (sessionUserId != board.getUser().getId()) { throw new Exception403("게시글 수정페이지로 이동할 권한이 없습니다"); } return board; } @Transactional public void save(BoardRequest.SaveDTO reqDTO, User sessionUser) { boardJPARepository.save(reqDTO.toEntity(sessionUser)); } }
 

5. BoardController 에 detail 수정하기

package shop.mtcoding.blog.board; import ch.qos.logback.core.model.Model; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import shop.mtcoding.blog._core.errors.exception.Exception403; import shop.mtcoding.blog._core.errors.exception.Exception404; import shop.mtcoding.blog.user.User; import java.lang.annotation.Native; import java.util.List; @RequiredArgsConstructor @Controller public class BoardController { private final BoardRepository boardRepository; private final HttpSession session; private final BoardService boardService; // @Transactional 트랜잭션 시간이 너무 길어져서 service에 넣어야함 @PostMapping("/board/{id}/update") public String update(@PathVariable Integer id, BoardRequest.UpdateDTO reqDTO) { User sessionUser = (User) session.getAttribute("sessionUser"); boardService.update(id, sessionUser.getId(), reqDTO); return "redirect:/board/" + id; } @GetMapping("/board/{id}/update-form") public String updateForm(@PathVariable(name = "id") Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardService.updateForm(id, sessionUser.getId()); request.setAttribute("board", board); return "/board/update-form"; // 서버가 내부적으로 index를 요청 - 외부에서는 다이렉트 접근이 안됨 } @PostMapping("/board/{id}/delete") public String delete(@PathVariable Integer id) { User sessionUser = (User) session.getAttribute("sessionUser"); boardService.delete(id, sessionUser.getId()); return "redirect:/"; } @GetMapping("/") public String index(HttpServletRequest request) { List<Board> boardList = boardService.findAll(); request.setAttribute("boardList", boardList); return "index"; // 서버가 내부적으로 index를 요청 - 외부에서는 다이렉트 접근이 안됨 } @PostMapping("/board/save") public String save(BoardRequest.SaveDTO reqDTO) { User sessionUser = (User) session.getAttribute("sessionUser"); boardService.save(reqDTO, sessionUser); return "redirect:/"; } @GetMapping("/board/save-form") public String saveForm() { return "board/save-form"; } @GetMapping("/board/{id}") public String detail(@PathVariable Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardService.detail(id, sessionUser); request.setAttribute("board", board); return "board/detail"; } }
notion image
 
Share article

vosw1