인스타그램 클론 프로젝트-(10)

  1. 인기페이지와 프로필페이지의 좋아요 구현

1) 인기페이지 구현
좋아요가 있는 사진들을 순서대로 출력, 좋아요가 많은 순으로

왜 api 컨트롤러로 안 하는지? api는 데이터를 리턴하는 서버이다.(ajax를 써야할 경우 api를 쓴다.) 인기페이지는 굳이 데이터를 리턴하는 서버로 만들지 않는다. 데이터를 들고 가기만 함.

api로 구현을 한다면? 브라우저에서 요청하는게 아니라 안드로이드, ios에서 요청을 한다면 데이터를 줘야 하므로 api로 구현해야한다.

(1) Controller

33줄 : 모델에 인기사진을 담아가야 하는데, 인기사진을 담는 service를 만들어서 List에 담는다.
35줄 : 모델에 담아서 /image/popular 페이지로 간다.

(2) Service

(3) Repository

mPopular()에서 쿼리로 함수를 만든다.(DB에서 먼저 해보고 만들기)

10줄 : imageId와 likeCount는 코드실행 시 오류가 생길 수 있으므로 image 테이블의 값만 들고오게 한다.

11줄 괄호 안 : 좋아요가 있는 imageId를 카운팅하는 likeCount라는 가상의 칼럼을 만들고, GROUP BY imageId로 묶으면, imageId 당 좋아요의 갯수를 셀 수 있다. 그걸 ORDER BY DESC 해주면 좋아요가 많은 순서로 정렬된다.

쿼리를 넣어 만든 Repository

(4) JSP

for문을 돌려서 출력한다.

2) 프로필 페이지의 좋아요 구현

profile.jsp에서 likeCount를 올려줘야 하는 부분 >> dto 안의 user 들을 select 할 때, 그 안의 image에서 likeCount가 있으니 이걸 활용하면 된다. >> DB에 데이터가 있는게 아니고 ImageService에서 만들어낸 것이다.

(1) 내부에서 연산해서 넣어주는 방법

ImageService에서 한 것처럼 만들어낸다.

dto에 들어가는 userEntity를 수정해서 연산해주도록 한다.

(2) 외부에서 연산해 넣어준다.

내부에서 dto에 값을 넣어주는 것보다 외부에서 연산하는게 더 간단하지만 연산은 내부에서 마쳐서 데이터만 가져가는게 좋다.

  1. 프로필 사진 변경 구현

1) 나의 프로필사진만 변경할 수 있게 하기

display:none 으로 보이지 않는다.
22~23줄의 이미지를 눌렀을 때, 모달이 뜬다.

114줄 : 모달에서 사진업로드 버튼을 누르면 profile.js의 profileImageUpload() 함수가 호출된다.

profileImageUpload()가 실행되면 userProfileImageInput을 강제로 클릭 이벤트 발생 >> 사진을 첨부할 수 있는 창이 뜬다.

화면에서 사진을 업로드 해서 바뀐 것을 DB에 반영이 되도록 서버 쪽으로 input 하는걸 만든다.

(1) 화면

JS에서 pageUserId와 principalId를 받아야 하므로 (로그인한 유저가 현재 페이지의 유저와 같은지를 알아야하므로) JSP에서 그 값을 받아서 넘긴다.

확인해보면, 아래처럼 로그인 유저와 프로필페이지의 유저가 다르다는 것을 알 수 있다. 이런 상황에서는 사진첨부하기 창이 뜨지 않도록 막는다.

if문으로 현재 페이지의 유저아이디(pageUserId)와 로그인한 유저아이디(principalId)가 같지 않으면 알람창 메시지와 return으로 아무것도 열리지 않는다.

서버에 이미지를 전송하게 하려면, form 태그에서 사진 데이터를 가져온다. 사진이므로 멀티파트 파일로 받아야 한다.

let profileImageForm=$("#userProfileImageForm");

으로 불러오게 했을 때, 콘솔로 확인하면 아래와 같이 배열로 뽑아오기 때문에 배열의 순서 0번째를 불러오게 한다.

profileImageForm 폼태그의 key/value 값들만 쌍으로 FormData 객체를 이용해 담아 ajax로 서버에 전송한다.

111줄 : image URL을 수정할 것이므로 타입은 'put'이다.
112줄 : 어떤 특정 유저의 프로필이미지만 수정을 한다는 의미.
114줄 : contentType >> 별도로 지정하지 않으면 디폴트가 x-wwww-form-urlencoded 값인데, 이 타입으로는 사진 전송이 되지 않으므로 false로 바꾼다. (필수)
115줄 : processData >> contentType을 false로 줬을 때, Quert String으로 자동설정 되므로 이것도 해체하기 위해 false로 준다.(ajax 사진전송을 하려면 필수)
116줄 : encType >> 사진전송을 위해 멀티파트 폼데이터로 설정(JSP의 해당태그에 설정하면 JS에서는 설정할 필요 없음)

(2) api

Controller

39줄 : 데이터(사진)를 보내므로 MultipartFile을 파라미터로 넣는다. 정확한 이름으로 보내야 한다. >> JSP input 태그의 name 값으로
※ Image Upload 구현 할 때는 ajax로 안 받고 dto(안에 Multipart 넣어서)로 데이터를 보냈음.(이유 :캡션도 같이 보내야 하므로)
40줄 : 프로필 사진이 변경이 되고 나면 세션값도 바뀌어야 하므로 넣어준다.
43줄 : 변경된 유저엔티티를 받아서 세션값에 넣어준다.>>세션변경
45줄 : 응답해줄 것이 없으므로 CMRespDto에 null 값을 넣는다.

Service

35줄 : put이면 DB를 변경하는 것 >> @Transactional(readOnly는 하지 않음)
37~48줄 : UUID를 쓰는 방법은 ImageService에서 ImageUpload의 코드를 가져와서 부분 수정해서 쓰면 된다.
38,45줄 : MultiParFile 자체가 파일이므로 getFile()은 뺀다.
41줄 : 업로드 경로를 설정위한 uploadFolder를 DI 해주기 위해 이 부분도 ImageService에서 가져온다.(32~33줄)

이렇게 하면 사진은 서버에 저장이 된다.

50줄 : 그리고 DB에 값을 넣어주기 위해 userRepository에서 id로 유저를 찾아오게 한다. 이때, 유저가 없을 경우를 위해 orElseThrow()로 익셉션처리를 해준다.
53줄 : 찾아서 업데이트 하기 >> set으로 ImageFileName을 저장 (save 필요없음)
54줄 : 세션 저장을 위해 리턴.(더티체킹으로 업데이트 된다.)

※serialize()는 key/value 데이터 던질 때 사용한다.(폼데이터는 사진 전송. 구분하기!!)

좋은 웹페이지 즐겨찾기