Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[리팩토링] Post, Service 코드 개선 및 테스트 코드 추가 #129

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
21 changes: 9 additions & 12 deletions src/main/java/com/yapp18/retrospect/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,16 @@ public ApiPagingResultResponse<PostDto.ListResponse> getPostsListCreatedAt(Long

// 회고글 상세페이지
@Transactional(isolation = Isolation.READ_COMMITTED)
public ApiIsResultResponse<PostDto.detailResponse> findPostContents(Long postIdx, Long userIdx){
public Post findPostContents(Long postIdx, Long userIdx){
Post post = postRepository.findById(postIdx)
.orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL));
// 조회수 증가
post.updateview(post.getView());

// 최근 읽은 글에 추가
if(userIdx != 0L){
listService.saveRecentReadPosts(userIdx, postIdx); // 최근 읽은 글에 추가
listService.saveRecentReadPosts(userIdx, postIdx);
}
return new ApiIsResultResponse<>(isWriter(post.getUser().getUserIdx(),userIdx),
isScrap(post, userIdx),
postMapper.postToDetailResponse(post)); // 작성자 판단
return post;
}


Expand Down Expand Up @@ -183,14 +181,13 @@ public Long updatePosts(Long userIdx,Long postIdx, PostDto.updateRequest request

// 회고글 삭제
@Transactional
public boolean deletePosts(Long userIdx,Long postIdx) {
public void deletePosts(Long userIdx,Long postIdx) {
Post post = postRepository.findById(postIdx)
.orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL));
if (isWriter(post.getUser().getUserIdx(), userIdx)){
if (!isWriter(post.getUser().getUserIdx(), userIdx)) throw new EntityNullException(ErrorInfo.POST_NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 AccessDeniedException을 던지는게 더 적절할 듯

else{
postRepository.deleteById(postIdx);
return true;
}
return false;
}


Expand All @@ -215,13 +212,13 @@ public boolean isView(User user, Long cursorId){


// 작성자 판별
private boolean isWriter(Long postUserIdx, Long userIdx){
public boolean isWriter(Long postUserIdx, Long userIdx){
if (userIdx == 0L) return false;
return postUserIdx.equals(userIdx);
}

// 스크랩 여부 판별 -> 리팩토링 필요
private boolean isScrap(Post post, Long userIdx){
public boolean isScrap(Post post, Long userIdx){
return likeRepository.findByPostAndUserUserIdx(post, userIdx).isPresent();
}

Expand Down
21 changes: 15 additions & 6 deletions src/main/java/com/yapp18/retrospect/service/SearchService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.yapp18.retrospect.service;

import com.yapp18.retrospect.config.ErrorInfo;
import com.yapp18.retrospect.domain.post.Post;
import com.yapp18.retrospect.domain.post.PostQueryRepository;
import com.yapp18.retrospect.domain.post.PostRepository;
import com.yapp18.retrospect.mapper.PostMapper;
import com.yapp18.retrospect.web.advice.EntityNullException;
import com.yapp18.retrospect.web.dto.ApiPagingResultResponse;
import com.yapp18.retrospect.web.dto.PostDto;
import com.yapp18.retrospect.web.dto.SearchDto;
Expand All @@ -30,15 +32,20 @@ public ApiPagingResultResponse<PostDto.ListResponse> searchByType(SearchDto sear
// 카테고리 검색 시
List<PostDto.ListResponse> result;
if (searchDto.getType().equals("category") && searchDto.getKeyword() == null){ // 검색타입이 카테고리고 키워드가 없음.
result = getPostCategory(searchDto.getPage(), pageable, searchDto.getQuery()) // cursorId, 페이지 정보, 쿼리 넘김(카테고리)
.stream().map(post->postMapper.postToListResponse(post, userIdx))
List<Post> posts = getPostCategory(searchDto.getPage(), pageable, searchDto.getQuery()) ;// cursorId, 페이지 정보, 쿼리 넘김(카테고리)
if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL);

result = posts.stream().map(post->postMapper.postToListResponse(post, userIdx))
.collect(Collectors.toList());
} else{
// 통합 검색 시
result = findAllByType(searchDto.getType(), searchDto.getQuery(), searchDto.getKeyword(), searchDto.getPage(),pageable)
.stream().map(post->postMapper.postToListResponse(post, userIdx))
List<Post> posts = findAllByType(searchDto.getType(), searchDto.getQuery(), searchDto.getKeyword(), searchDto.getPage(),pageable);
if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL);

result = posts.stream().map(post->postMapper.postToListResponse(post, userIdx))
.collect(Collectors.toList());
}

Long lastIdx = result.isEmpty() ? null : result.get(result.size()-1).getPostIdx();
return new ApiPagingResultResponse<>(isNext(searchDto, pageable, lastIdx), result);
}
Expand All @@ -47,15 +54,17 @@ public ApiPagingResultResponse<PostDto.ListResponse> searchByType(SearchDto sear
// 해시태그로 검색
@Transactional(readOnly = true)
public ApiPagingResultResponse<PostDto.ListResponse> getPostsByHashTag(String tag, Long cursorId, Pageable pageable, Long userIdx){
List<PostDto.ListResponse> result = findAllByTag(cursorId, pageable, tag).stream()
List<Post> posts = findAllByTag(cursorId, pageable, tag);
if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL);

List<PostDto.ListResponse> result= posts.stream()
.map(post->postMapper.postToListResponse(post, userIdx))
.collect(Collectors.toList());
Long lastIdx = result.isEmpty() ? null : result.get(result.size()-1).getPostIdx();
return new ApiPagingResultResponse<>(isHashTag(lastIdx, pageable, tag), result);
}



// 통합 검색 분기처리
private List<Post> findAllByType(String type, String query, String keyword, Long cursorId, Pageable page){
return cursorId == null || cursorId == 0 ?
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/yapp18/retrospect/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,9 @@ public User findByUserEmail(String email){
return userRepository.findByEmail(email)
.orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL));
}


public Long getUserInfoFromToken(User user){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@currentuser는 @AuthenticationPrincipal을 기반으로 만든건데 스프링 시큐리티에서 인증된 사용자 정보는 CustomUserDetailsService.loadUserByUsername으로 DB에서 Entity를 가져오게 되어있거든.
따라서 인증에 실패하면 UnAuthorized로 응답하게 되서 User 객체는 null 체크를 해줄 필요가 없는데 이 함수의 용도를 잘 모르겠어.
잘 이해가 안된다면 https://ncucu.me/137, https://jjeda.tistory.com/7를 참고해봐!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@currentuser 보니까 @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : user") 이 부분에서
anonymousUser이면 nulㅣ이 반환되고 아니면 user이 반환되는건가? 싶어서 처리해놨어 어제 물어보고싶었던게 이부분ㅠ
null check가 필요없다면 수정해놓겟습니더!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

익명 사용자 접근은 어차피 권한에 따라 SecurityConfig filter에서 걸러지기 때문에 null 신경 안써도 될 꺼같아

return (user != null)? user.getUserIdx(): 0L;
}
}
102 changes: 46 additions & 56 deletions src/main/java/com/yapp18/retrospect/web/controller/PostController.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package com.yapp18.retrospect.web.controller;


import com.yapp18.retrospect.annotation.CurrentUser;
import com.yapp18.retrospect.config.ResponseMessage;
import com.yapp18.retrospect.domain.post.Post;
import com.yapp18.retrospect.domain.user.User;
import com.yapp18.retrospect.mapper.PostMapper;
import com.yapp18.retrospect.service.PostService;
import com.yapp18.retrospect.service.TokenService;
import com.yapp18.retrospect.service.UserService;
import com.yapp18.retrospect.web.dto.ApiDefaultResponse;
import com.yapp18.retrospect.web.dto.ApiIsResultResponse;
import com.yapp18.retrospect.web.dto.PostDto;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,30 +30,22 @@ public class PostController {

private final PostService postService;
private final TokenService tokenService;
private final UserService userService;
private final PostMapper postMapper;
private static final int DEFAULT_SIZE = 20;

// @ApiOperation(value = "main", notes = "[메인] 회고글 목록 조회, 최신순") // api tag, 설명
// @GetMapping("/lists/new")
// public ResponseEntity<Object> getMainPosts(@ApiParam(value = "현재 페이지 마지막 post_idx", required = true, example = "20")
// HttpServletRequest request,
// @RequestParam(value = "page", defaultValue = "0") Long page,
// @RequestParam(value = "pageSize",defaultValue = "20") Integer pageSize){
// if (pageSize == null) pageSize = DEFAULT_SIZE;
// Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L;
// return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_FIND_RECENT.getResponseMessage(),
// postService.getPostsListRecent(page, PageRequest.of(0, pageSize), userIdx)), HttpStatus.OK);
// }

@ApiOperation(value = "main", notes = "[메인] 회고글 목록 조회, 누적조회순")
@GetMapping("/lists")
public ResponseEntity<Object> getMainPostsOrderByView(@ApiParam(value = "현재 페이지 마지막 post_idx", required = true, example = "20")
HttpServletRequest request,
@RequestParam(value = "page", defaultValue = "0") Long page,
@RequestParam(value = "pageSize") Integer pageSize){
@CurrentUser User user,
@RequestParam(value = "page", defaultValue = "0") Long page,
@RequestParam(value = "pageSize") Integer pageSize){
if (pageSize == null) pageSize = DEFAULT_SIZE;
Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L;
return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_FIND_VIEW.getResponseMessage(),
postService.getPostsListView(page, PageRequest.of(0, pageSize), userIdx)), HttpStatus.OK);

return ResponseEntity.status(HttpStatus.OK).body(
ApiDefaultResponse.res(200,
ResponseMessage.POST_FIND_VIEW.getResponseMessage(),
postService.getPostsListView(page, PageRequest.of(0,pageSize), userService.getUserInfoFromToken(user))));
}

@ApiOperation(value = "main", notes = "[프로필] 유저 회고글 목록 조회, 생성일자순")
Expand All @@ -57,68 +55,60 @@ public ResponseEntity<Object> getPostsByUserIdxOrderByCreatedAtDesc(@ApiParam(va
@RequestParam(value = "page", defaultValue = "0") Long page,
@RequestParam(value = "pageSize") Integer pageSize){
if (pageSize == null) pageSize = DEFAULT_SIZE;
return new ResponseEntity<>(ApiDefaultResponse.res(200,
ResponseMessage.POST_FIND_CREATED.getResponseMessage(),
postService.getPostsListCreatedAt(page, userIdx, PageRequest.of(0, pageSize))), HttpStatus.OK);
return ResponseEntity.status(HttpStatus.OK).body(
ApiDefaultResponse.res(200, ResponseMessage.POST_FIND_CREATED.getResponseMessage(),
postService.getPostsListCreatedAt(page, userIdx, PageRequest.of(0, pageSize))));
}


@ApiOperation(value = "detail", notes = "[상세] 회고글 상세보기")
@GetMapping("/{postIdx}")
public ResponseEntity<Object> findPostsContentById(HttpServletRequest request,
public ResponseEntity<Object> findPostsContentById(@CurrentUser User user,
@ApiParam(value = "상세보기 post_idx", required = true, example = "3")
@PathVariable(value = "postIdx") Long postIdx) {
Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L;
return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_DETAIL.getResponseMessage(),
postService.findPostContents(postIdx, userIdx)), HttpStatus.OK);
}

Long userIdx = userService.getUserInfoFromToken(user);
Post post = postService.findPostContents(postIdx, userIdx);

return ResponseEntity.status(HttpStatus.OK).body(
new ApiIsResultResponse<>(postService.isWriter(post.getUser().getUserIdx(), userIdx),
postService.isScrap(post, userIdx),
postMapper.postToDetailResponse(post))
);
}

@ApiOperation(value = "main", notes = "[메인]회고글 저장하기")
@PostMapping("")
public ResponseEntity<Object> inputPosts(HttpServletRequest request,
public ResponseEntity<Object> inputPosts(@CurrentUser User user,
@RequestBody PostDto.saveResponse saveResponse){
Long postIdx = postService.inputPosts(saveResponse, tokenService.getUserIdx(tokenService.getTokenFromRequest(request)));
return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_SAVE.getResponseMessage(), postIdx), HttpStatus.OK);
Long userIdx = userService.getUserInfoFromToken(user);
Long postIdx = postService.inputPosts(saveResponse, userIdx);
return ResponseEntity.status(HttpStatus.OK).body(
ApiDefaultResponse.res(200, ResponseMessage.POST_SAVE.getResponseMessage(), postIdx)
);
}

@ApiOperation(value = "mypage", notes = "[마이페이지]회고글 수정하기")
@PutMapping("/{postIdx}")
public ResponseEntity<Object> updatePosts(HttpServletRequest request,
public ResponseEntity<Object> updatePosts(@CurrentUser User user,
@ApiParam(value = "회고글 post_idx", required = true, example = "1")
@PathVariable(value = "postIdx") Long postIdx, @RequestBody PostDto.updateRequest requestDto){
Long post = postService.updatePosts(tokenService.getUserIdx(tokenService.getTokenFromRequest(request)), postIdx, requestDto);
return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_UPDATE.getResponseMessage(),post),HttpStatus.OK);
Long userIdx = userService.getUserInfoFromToken(user);
Long post = postService.updatePosts(userIdx, postIdx, requestDto);
return ResponseEntity.status(HttpStatus.OK).body(
ApiDefaultResponse.res(200, ResponseMessage.POST_UPDATE.getResponseMessage(), post)
);
}

@ApiOperation(value = "mypage", notes = "[마이페이지]회고글 삭제하기")
@DeleteMapping("/{postIdx}")
public ResponseEntity<Object> deletePosts(HttpServletRequest request,
public ResponseEntity<Object> deletePosts(@CurrentUser User user,
@ApiParam(value = "회고글 post_idx", required = true, example = "1")
@PathVariable(value = "postIdx") Long postIdx){
boolean isPost = postService.deletePosts(tokenService.getUserIdx(tokenService.getTokenFromRequest(request)),postIdx);
if (!isPost){
return new ResponseEntity<>(ApiDefaultResponse.res(400,"삭제할 idx 없음...", false),HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(ApiDefaultResponse.res(200, ResponseMessage.POST_DELETE.getResponseMessage(), true),HttpStatus.OK);
postService.deletePosts(userService.getUserInfoFromToken(user),postIdx);
return ResponseEntity.status(HttpStatus.OK).body(
ApiDefaultResponse.res(200, ResponseMessage.POST_DELETE.getResponseMessage())
);
}


// @ApiOperation(value = "main", notes = "[메인] 카테고리 필터링")
// @GetMapping("/lists/category")
// public ResponseEntity<Object> findPostsByCategory(HttpServletRequest request,
// @ApiParam(value = "카테고리", required = true, example = "design")
// @RequestParam(value = "query") String query,
// @ApiParam(value = "page", required = true, example = "0")
// @RequestParam(value = "page") Long page,
// @ApiParam(value = "pageSize", required = true, example = "20")
// @RequestParam(value = "pageSize") Integer pageSize
// ){
// if (pageSize == null) pageSize = DEFAULT_SIZE;
// System.out.println("_---->" + request.getQueryString());
// System.out.println(query);
// Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L;
// return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_FIND_CATEGORY.getResponseMessage(),
// postService.getPostsByCategory(query, page, PageRequest.of(0,pageSize), userIdx)), HttpStatus.OK);
// }
}