Search

50. 스프링부트 포토그램 프로필 페이지 DTO로 페이지 완성하기

프로필 페이지

ssar
cos
love
이렇게 3개의 계정으로 가입해서 만들어주고 ssar로 로그인.
http://localhost:8080/user/2
user/2로가면 코스는 내계정이 아니니까 사진등록이라는 버튼이 생기면 안된다.
내 계정에는 구독하기 버튼 노출x
다른계정의 프로필에는 사진등록 버튼 노출x
로 수정해줘야 한다.
DTO를 새로 생성해줘야하는데
web > dto > user 폴더에 UserProfileDto.java 생성
package com.cos.photogramstart.web.dto.user; import com.cos.photogramstart.domain.user.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Builder @AllArgsConstructor @NoArgsConstructor @Data public class UserProfileDto { private int isPageOwner; private User user; }
Java
복사
profile.jsp에서
<c:choose> <c:when test=""> </c:when> <c:otherwise> </c:otherwise> </c:choose>
Java
복사
이런식으로 버튼쪽에 추가해주면 조건문처러 사용할수있다.
<c:choose> <c:when test="${principal.user.id == user.id}"> <button class="cta" onclick="location.href='/image/upload'">사진등록</button> </c:when> <c:otherwise> <button class="cta" onclick="toggleSubscribe(this)">구독하기</button> </c:otherwise> </c:choose>
Java
복사
내계정일때 구독하기 버튼도 안뜨고
남의 계정에도 사진등록버튼이 안뜬다!
근데 이렇게 jsp에 로직넣는걸 추천하진 않는다.
애초에 조건로직을 만들어진 상태에서 넘어와서 넣어줄거다.
UserService.java에 회원프로필 함수에서 UserProfileDto를 추가해주면서 주인인지 주인아닌지에 대한 구분값을 넘겨줄거다.
@Transactional(readOnly = true) public User 회원프로필(int userId) { UserProfileDto dto = new UserProfileDto(); // SELECT * FROM image WHERE userId = :userId; User userEntity = userRepository.findById(userId).orElseThrow(()->{ throw new CustomException("해당 프로필 페이지는 없는 페이지입니다."); }); dto.setUser(userEntity); dto.setIsPageOwner(1); // 1은 페이지 주인 , -1은 주인이 아님. return userEntity; }
Java
복사
그리고 UserController.java에서 profile 매핑어노테이션에
@GetMapping("/user/{id}")
Java
복사
id 변수명이 알아보기 힘드니까
@GetMapping("/user/{pageUserId}")
Java
복사
로 보기 좋게 변경해준다.
@GetMapping("/user/{pageUserId}") public String profile(@PathVariable int pageUserId, Model model) { User userEntity = userService.회원프로필(pageUserId); model.addAttribute("user", userEntity); return "user/profile"; }
Java
복사
그러면 로그인한 사람의 아이디가 아니라 현재 페이지의 아이디가 오는구나 라고 알아보기 쉽다
UserService도 변수명 변경해주기
@Transactional(readOnly = true) public User 회원프로필(int pageUserId) { UserProfileDto dto = new UserProfileDto(); // SELECT * FROM image WHERE userId = :userId; User userEntity = userRepository.findById(pageUserId).orElseThrow(()->{ throw new CustomException("해당 프로필 페이지는 없는 페이지입니다."); }); dto.setUser(userEntity); dto.setIsPageOwner(1); // 1은 페이지 주인 , -1은 주인이 아님. return userEntity; }
Java
복사
이제 그러면 여기서 로그인한 사람의 아이디를 받아와서 비교해줘야한다.
public User 회원프로필(int pageUserId, int principalId) {
Java
복사
UserController에도 로그인한 사람 id를 던져준다
@GetMapping("/user/{pageUserId}") public String profile(@PathVariable int pageUserId, Model model, @AuthenticationPrincipal PrincipalDetails principalDetails) { User userEntity = userService.회원프로필(pageUserId, principalDetails.getUser().getId()); model.addAttribute("user", userEntity); return "user/profile"; }
Java
복사
아까 서비스에서 비교문 추가해줘서 넘겨준다
dto.setIsPageOwner(pageUserId == principalId ? 1 : -1 ); // 1은 페이지 주인 , -1은 주인이 아님.
Java
복사
그러면 dto로 리턴시켜줘야하니까 리턴타입도 dto로 바꿔준다
@Transactional(readOnly = true) public UserProfileDto 회원프로필(int pageUserId, int principalId) { UserProfileDto dto = new UserProfileDto(); // SELECT * FROM image WHERE userId = :userId; User userEntity = userRepository.findById(pageUserId).orElseThrow(()->{ throw new CustomException("해당 프로필 페이지는 없는 페이지입니다."); }); dto.setUser(userEntity); dto.setIsPageOwner(pageUserId == principalId ? 1 : -1 ); // 1은 페이지 주인 , -1은 주인이 아님. return dto; }
Java
복사
컨트롤러에서도 user를 넘겨주는게 아니라 dto로 넘겨줘야한다
@GetMapping("/user/{pageUserId}") public String profile(@PathVariable int pageUserId, Model model, @AuthenticationPrincipal PrincipalDetails principalDetails) { UserProfileDto dto = userService.회원프로필(pageUserId, principalDetails.getUser().getId()); model.addAttribute("dto", dto); return "user/profile"; }
Java
복사
그러면 profile.jsp에서 ${user.name} 을 ${dto.user.name} 이런식으로 변경해줘야한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="../layout/header.jsp"%> <!--프로필 섹션--> <section class="profile"> <!--유저정보 컨테이너--> <div class="profileContainer"> <!--유저이미지--> <div class="profile-left"> <div class="profile-img-wrap story-border" onclick="popup('.modal-image')"> <form id="userProfileImageForm"> <input type="file" name="profileImageFile" style="display: none;" id="userProfileImageInput" /> </form> <img class="profile-image" src="#" onerror="this.src='/images/person.jpeg'" id="userProfileImage" /> </div> </div> <!--유저이미지end--> <!--유저정보 및 사진등록 구독하기--> <div class="profile-right"> <div class="name-group"> <h2>${dto.user.name}</h2> <c:choose> <c:when test="${dto.isPageOwner}"> <button class="cta" onclick="location.href='/image/upload'">사진등록</button> </c:when> <c:otherwise> <button class="cta" onclick="toggleSubscribe(this)">구독하기</button> </c:otherwise> </c:choose> <button class="modi" onclick="popup('.modal-info')"> <i class="fas fa-cog"></i> </button> </div> <div class="subscribe"> <ul> <li><a href=""> 게시물<span>${dto.user.images.size()}</span> </a></li> <li><a href="javascript:subscribeInfoModalOpen();"> 구독정보<span>2</span> </a></li> </ul> </div> <div class="state"> <h4>${dto.user.bio}</h4> <h4>${dto.user.website}</h4> </div> </div> <!--유저정보 및 사진등록 구독하기--> </div> </section> <!--게시물컨섹션--> <section id="tab-content"> <!--게시물컨컨테이너--> <div class="profileContainer"> <!--그냥 감싸는 div (지우면이미지커짐)--> <div id="tab-1-content" class="tab-content-item show"> <!--게시물컨 그리드배열--> <div class="tab-1-content-inner"> <!--아이템들--> <c:forEach var="image" items="${user.images}"> <!--EL 표현식에서 변수명을 적으면 get함수가 자동 호출된다. --> <div class="img-box"> <a href=""> <img src="/upload/${image.postImageUrl}" /> </a> <div class="comment"> <a href="#" class=""> <i class="fas fa-heart"></i><span>0</span> </a> </div> </div> </c:forEach> <!--아이템들end--> </div> </div> </div> </section> <!--로그아웃, 회원정보변경 모달--> <div class="modal-info" onclick="modalInfo()"> <div class="modal"> <button onclick="location.href='/user/1/update'">회원정보 변경</button> <button onclick="location.href='/logout'">로그아웃</button> <button onclick="closePopup('.modal-info')">취소</button> </div> </div> <!--로그아웃, 회원정보변경 모달 end--> <!--프로필사진 바꾸기 모달--> <div class="modal-image" onclick="modalImage()"> <div class="modal"> <p>프로필 사진 바꾸기</p> <button onclick="profileImageUpload()">사진 업로드</button> <button onclick="closePopup('.modal-image')">취소</button> </div> </div> <!--프로필사진 바꾸기 모달end--> <div class="modal-subscribe"> <div class="subscribe"> <div class="subscribe-header"> <span>구독정보</span> <button onclick="modalClose()"> <i class="fas fa-times"></i> </button> </div> <div class="subscribe-list" id="subscribeModalList"> <div class="subscribe__item" id="subscribeModalItem-1"> <div class="subscribe__img"> <img src="#" onerror="this.src='/images/person.jpeg'"/> </div> <div class="subscribe__text"> <h2>love</h2> </div> <div class="subscribe__btn"> <button class="cta blue" onclick="toggleSubscribeModal(this)">구독취소</button> </div> </div> <div class="subscribe__item" id="subscribeModalItem-2"> <div class="subscribe__img"> <img src="#" onerror="this.src='/images/person.jpeg'"/> </div> <div class="subscribe__text"> <h2>ssar</h2> </div> <div class="subscribe__btn"> <button class="cta blue" onclick="toggleSubscribeModal(this)">구독취소</button> </div> </div> </div> </div> </div> <script src="/js/profile.js"></script> <%@ include file="../layout/footer.jsp"%>
Java
복사
<c:when test="${dto.isPageOwner}">
Java
복사
근데 이게 1로와서 true라고 구분하기가 힘들다 그래서 int 로 잡았던 부분을 boolean 으로 변경해준다
UserProfileDto
@Builder @AllArgsConstructor @NoArgsConstructor @Data public class UserProfileDto { private boolean pageOwnerState; private User user; }
Java
복사
UserService
dto.setPageOwnerState(pageUserId == principalId);
Java
복사
profile.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="../layout/header.jsp"%> <!--프로필 섹션--> <section class="profile"> <!--유저정보 컨테이너--> <div class="profileContainer"> <!--유저이미지--> <div class="profile-left"> <div class="profile-img-wrap story-border" onclick="popup('.modal-image')"> <form id="userProfileImageForm"> <input type="file" name="profileImageFile" style="display: none;" id="userProfileImageInput" /> </form> <img class="profile-image" src="#" onerror="this.src='/images/person.jpeg'" id="userProfileImage" /> </div> </div> <!--유저이미지end--> <!--유저정보 및 사진등록 구독하기--> <div class="profile-right"> <div class="name-group"> <h2>${dto.user.name}</h2> <c:choose> <c:when test="${dto.pageOwnerState}"> <button class="cta" onclick="location.href='/image/upload'">사진등록</button> </c:when> <c:otherwise> <button class="cta" onclick="toggleSubscribe(this)">구독하기</button> </c:otherwise> </c:choose> <button class="modi" onclick="popup('.modal-info')"> <i class="fas fa-cog"></i> </button> </div> <div class="subscribe"> <ul> <li><a href=""> 게시물<span>${dto.user.images.size()}</span> </a></li> <li><a href="javascript:subscribeInfoModalOpen();"> 구독정보<span>2</span> </a></li> </ul> </div> <div class="state"> <h4>${dto.user.bio}</h4> <h4>${dto.user.website}</h4> </div> </div> <!--유저정보 및 사진등록 구독하기--> </div> </section> <!--게시물컨섹션--> <section id="tab-content"> <!--게시물컨컨테이너--> <div class="profileContainer"> <!--그냥 감싸는 div (지우면이미지커짐)--> <div id="tab-1-content" class="tab-content-item show"> <!--게시물컨 그리드배열--> <div class="tab-1-content-inner"> <!--아이템들--> <c:forEach var="image" items="${dto.user.images}"> <!--EL 표현식에서 변수명을 적으면 get함수가 자동 호출된다. --> <div class="img-box"> <a href=""> <img src="/upload/${image.postImageUrl}" /> </a> <div class="comment"> <a href="#" class=""> <i class="fas fa-heart"></i><span>0</span> </a> </div> </div> </c:forEach> <!--아이템들end--> </div> </div> </div> </section> <!--로그아웃, 회원정보변경 모달--> <div class="modal-info" onclick="modalInfo()"> <div class="modal"> <button onclick="location.href='/user/1/update'">회원정보 변경</button> <button onclick="location.href='/logout'">로그아웃</button> <button onclick="closePopup('.modal-info')">취소</button> </div> </div> <!--로그아웃, 회원정보변경 모달 end--> <!--프로필사진 바꾸기 모달--> <div class="modal-image" onclick="modalImage()"> <div class="modal"> <p>프로필 사진 바꾸기</p> <button onclick="profileImageUpload()">사진 업로드</button> <button onclick="closePopup('.modal-image')">취소</button> </div> </div> <!--프로필사진 바꾸기 모달end--> <div class="modal-subscribe"> <div class="subscribe"> <div class="subscribe-header"> <span>구독정보</span> <button onclick="modalClose()"> <i class="fas fa-times"></i> </button> </div> <div class="subscribe-list" id="subscribeModalList"> <div class="subscribe__item" id="subscribeModalItem-1"> <div class="subscribe__img"> <img src="#" onerror="this.src='/images/person.jpeg'"/> </div> <div class="subscribe__text"> <h2>love</h2> </div> <div class="subscribe__btn"> <button class="cta blue" onclick="toggleSubscribeModal(this)">구독취소</button> </div> </div> <div class="subscribe__item" id="subscribeModalItem-2"> <div class="subscribe__img"> <img src="#" onerror="this.src='/images/person.jpeg'"/> </div> <div class="subscribe__text"> <h2>ssar</h2> </div> <div class="subscribe__btn"> <button class="cta blue" onclick="toggleSubscribeModal(this)">구독취소</button> </div> </div> </div> </div> </div> <script src="/js/profile.js"></script> <%@ include file="../layout/footer.jsp"%>
Java
복사
내 계정 프로필화면
남의 프로필화면
근데 view단에서 이렇게 size()로 연산해서 처리하는건 안좋다.
미리 갯수를 받아와서 뿌려주는걸로 변경해주자.
UserProfileDto
private int imageCount;
Java
복사
추가
UserService의 회원프로필 함수에
dto.setImageCount(userEntity.getImages().size());
Java
복사
profile.jsp
<li><a href=""> 게시물<span>${dto.imageCount}</span>
Java
복사
게시물 갯수도 잘나온다!

*참고