Skip to content

Commit

Permalink
post 로직 수정 및 기본 예외처리 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
3un0ia committed Mar 25, 2024
1 parent 6efbe86 commit 548f67b
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package JWTLogIn.JWT.common.exception;

public abstract class CommonException extends RuntimeException {

protected CommonException () {
}

protected CommonException(Exception e) {
super(e);
}

protected CommonException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package JWTLogIn.JWT.common.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ExceptionAdvice { // Exception Handler
Logger defaultLog = LoggerFactory.getLogger(ExceptionAdvice.class);
Logger exceptionLog = LoggerFactory.getLogger("ExceptionLogger");

@ExceptionHandler(CommonException.class)
public ResponseEntity<ExceptionResponse> handleCommonException(CommonException e) {
ExceptionSituation exceptionSituation = ExceptionMapper.getSituationOf(e);

defaultLog.warn(exceptionSituation.getMessage());
exceptionLog.warn(exceptionSituation.getMessage(), e);

return ResponseEntity.status(exceptionSituation.getStatusCode())
.body(ExceptionResponse.from(exceptionSituation));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<Void> handleException(Exception e) {
defaultLog.error(e.getMessage());
exceptionLog.error(e.getMessage(), e);

return ResponseEntity.internalServerError().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package JWTLogIn.JWT.common.exception;

import JWTLogIn.JWT.post.exception.IsNotNoticeException;
import JWTLogIn.JWT.post.exception.PostNotFoundException;
import JWTLogIn.JWT.user.exception.HasNoAuthorityException;
import JWTLogIn.JWT.user.exception.UserNotFoundException;
import org.springframework.http.HttpStatus;

import java.util.LinkedHashMap;
import java.util.Map;

public class ExceptionMapper { // 예외 객체 -> 예외 상태로 바꿔주는 mapper

private static final Map<Class<? extends Exception>, ExceptionSituation> mapper = new LinkedHashMap<>();

static {
setUpUserException();
setUpPostException();
// setUpReplyException();
}

private static void setUpUserException() {
mapper.put(UserNotFoundException.class,
ExceptionSituation.of("해당 유저를 찾을 수 없습니다", HttpStatus.NOT_FOUND, 404));
mapper.put(HasNoAuthorityException.class,
ExceptionSituation.of("유저에 대한 접근 권한이 부족합니다", HttpStatus.FORBIDDEN, 403));
}

private static void setUpPostException() {
mapper.put(PostNotFoundException.class,
ExceptionSituation.of("해당 공지를 찾을 수 없습니다", HttpStatus.NOT_FOUND, 404));
mapper.put(IsNotNoticeException.class,
ExceptionSituation.of("요청된 게시글은 공지가 아닙니다", HttpStatus.BAD_REQUEST, 400));
}


public static ExceptionSituation getSituationOf(Exception exception) {
return mapper.get(exception.getClass());
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package JWTLogIn.JWT.common.exception;

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public record ExceptionResponse(int code, String message) {

public static ExceptionResponse from(ExceptionSituation exceptionSituation) {
return new ExceptionResponse(exceptionSituation.getErrorCode(), exceptionSituation.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package JWTLogIn.JWT.common.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@AllArgsConstructor
@Getter
public class ExceptionSituation {
private final String message;
private final HttpStatus statusCode;
private final int errorCode;

public static ExceptionSituation of(String message, HttpStatus statusCode, int errorCode) {
return new ExceptionSituation(message, statusCode, errorCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,20 @@ public ResponseEntity<List<PostDto>> searchPost(@RequestParam String text)
return ResponseEntity.ok(postDtos);
}

@PostMapping("/notice/post/{userId}") // 공지 작성 - POST, /tgwing.kr/notice/post
public ResponseEntity<PostDto> post(@RequestBody PostDto requestDto,
@PathVariable("userId") Long userId)
@PostMapping("/notice/post") // 공지 작성 - POST, /tgwing.kr/notice/post
public ResponseEntity<PostDto> post(@RequestBody PostDto requestDto)
{
System.out.println("-- Post new post --");
System.out.println("Request Dto = " + requestDto);
// RequestDTO : title, content, thumbnail(선택)
// userId : 해당 URL을 요청한 유저의 Id
// RequestDTO : writer, title, content, thumbnail(선택)

// dto 가져온 값을 엔티티로 바꾸고 DB에 save
// 다시 꺼내와서 완성된 객체의 구성요소(id, title, description, writtenDate ...)

// 유저의 level 확인 필요 - level = MANAGER인 경우에만 작성가능
// 로그인 되어있지 않은 경우 NORMAL, 로그인 된 경우 MEMBER, 관리자인 경우 MANAGER

PostDto responseDto = postService.createPost(requestDto, userId);
PostDto responseDto = postService.createPost(requestDto);
return ResponseEntity.ok(responseDto);
}
// @CrossOrigin
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package JWTLogIn.JWT.post.exception;

import JWTLogIn.JWT.common.exception.CommonException;

public class IsNotNoticeException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package JWTLogIn.JWT.post.exception;

import JWTLogIn.JWT.common.exception.CommonException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class PostNotFoundException extends CommonException {
}
122 changes: 62 additions & 60 deletions JWT/src/main/java/JWTLogIn/JWT/post/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import JWTLogIn.JWT.post.dto.PostDto;
import JWTLogIn.JWT.post.entity.PostEntity;
import JWTLogIn.JWT.post.entity.Type;
import JWTLogIn.JWT.post.exception.IsNotNoticeException;
import JWTLogIn.JWT.post.exception.PostNotFoundException;
import JWTLogIn.JWT.post.repository.PostRepository;
import JWTLogIn.JWT.user.entity.UserEntity;
import JWTLogIn.JWT.user.entity.Enum.Level;
import JWTLogIn.JWT.user.entity.Enum.Status;
import JWTLogIn.JWT.user.exception.HasNoAuthorityException;
import JWTLogIn.JWT.user.exception.UserNotFoundException;
import JWTLogIn.JWT.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -37,45 +41,35 @@ public class PostService {
@Autowired
private final UserRepository userRepository;

public List<PostDto> getAllPosts() {

// List<PostDto> dtos = new ArrayList<>();

// List<PostEntity> entities = postRepository.findAll();
public List<PostDto> getAllPosts() { // 모든 공지 가져오기
// findAllNotice() : type=NOT인 post를 모두 가져옴
List<PostEntity> allPosts = postRepository.findAllNotice();
// DB에서 가져온 모든 POST 중에서 type = NOT인 게시글을 모두 가져옴


if (allPosts.isEmpty()) {throw new ResponseStatusException(HttpStatus.NOT_FOUND);}
// 가져온 List가 비어있는 경우 == 공지 없음
if (allPosts.isEmpty()) throw new PostNotFoundException();

List<PostDto> dtos = allPosts.stream().map(postEntity -> toDto(postEntity)).collect(Collectors.toList());

for (PostDto dto : dtos) {
System.out.println("dto = " + dto);
}

return dtos;
}

public PostEntity getPostInfo(Long id) // 특정 게시글 가져오기
public PostEntity getPostInfo(Long id) // 특정 게시글 정보 모두 보내기 (엔티티로 바로 응답)
{
// 입력된 id에 해당하는 글 찾기
Optional<PostEntity> postEntityInOp = postRepository.findById(id);
PostEntity postEntity = postEntityInOp.orElseThrow();
// 관리자 여부 확인
if (postEntity.getType() == Type.NOT) { return postEntity; }
else return null;
PostEntity postEntity = postEntityInOp.orElseThrow(PostNotFoundException::new);
// 공지인지 확인
if (postEntity.getType() == Type.NOT) { return postEntity; } // 엔티티 바로 보내기
else throw new IsNotNoticeException();
}
public PostDto getPost(Long id) // 특정 게시글 가져오기
{
// 입력된 id에 해당하는 글 찾기
Optional<PostEntity> postEntityInOp = postRepository.findById(id);
PostEntity postEntity = postEntityInOp.orElseThrow();
// 관리자 여부 확인
if (postEntity.getType() == Type.NOT) {
return toDto(postEntity);
}
else return null;
PostEntity postEntity = postEntityInOp.orElseThrow(PostNotFoundException::new);

// 공지인지 확인
if (postEntity.getType() == Type.NOT) return toDto(postEntity); // dto로 변환해서 보내기
else throw new IsNotNoticeException();
}

// @Transactional
Expand All @@ -102,59 +96,67 @@ public PostDto getPost(Long id) // 특정 게시글 가져오기
// }


public List<PostDto> searchPosts(String search)
public List<PostDto> searchPosts(String search) // 공지 내용으로 검색하기
{
List<PostDto> postDtos = new ArrayList<>();
// findByContentContains() : 검색한 text를 포함하고 있는 공지를 모두 가져옴
List<PostEntity> searchedEntity = postRepository.findByContentContains(search);
// 가져온 List가 비어있는 경우 == 공지 없음
if (searchedEntity.isEmpty()) throw new PostNotFoundException();

// 공지인지 확인 후 dto list에 담고, 공지가 아닌 경우 null로 변환
List<PostDto> postDtos = searchedEntity.stream().map(postEntity -> {
if(postEntity.getType() == Type.NOT) return toDto(postEntity);
else return null;
}).collect(Collectors.toList());

// null 제거
while(postDtos.remove(null)){}

List<PostEntity> SearchedEntity = postRepository.findByContentContains(search);
for (PostEntity postEntity : SearchedEntity) {
// System.out.println("postEntity = " + postEntity);
postDtos.add(toDto(postEntity));
}
return postDtos;
}

public PostDto createPost(PostDto requestDto, Long userId) // 게시글 생성하기
public PostDto createPost(PostDto requestDto) // 공지 생성하기
{
// 글을 작성할 user 조회
Optional<UserEntity> userById = userRepository.findById(userId);
Optional<UserEntity> userById = userRepository.findById(requestDto.getWriter());
// userEntity를 받아오지 못한 경우 - 회원을 찾을 수 없음 (Exception)
UserEntity userEntity = userById.orElseThrow(UserNotFoundException::new);

// else { // user 조회되면, user name을 author로 설정
// UserEntity userEntity = byId.get();
// dto.setAuthor(userEntity.getName());
// }
if(userById.isPresent()) {
UserEntity userEntity = userById.orElseThrow();
// if (userEntity.getLevel() == Level.MANAGER) {

if(true) {
PostEntity postEntity = toEntity(requestDto); // DTO 기반으로 엔티티 생성 - writer는 요청된 user의 ID
System.out.println("postEntity = " + postEntity); // 생성된 엔티티 확인

PostEntity savedEntity = postRepository.save(postEntity);
PostDto responseDto = toDto(savedEntity);
return responseDto;

} else {
// 공지 생성 불가능 (level이 NORMAL, MEMBER인 경우)
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
}
else {
// 공지 생성 불가능 (등록되지 않은 회원인 경우)
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
/**
* requestDTO에 받아올 정보 : title, content, thumbnail + writer(userId)를 함께 받아와야 함
*/

// authService.extractStudentId(jwt); --> userEntity.getStudentId()와 같은지 확인 필요 (URL 요청자와 요청 JSON 정보가 같은지)

// if (userEntity.getLevel() == Level.MANAGER) { // user가 관리자 level인 경우에만 동작
if(true) { // level 해결까지는 무조건 if 통과
PostEntity postEntity = toEntity(requestDto); // DTO 기반으로 엔티티 생성 - writer는 요청된 user의 ID

System.out.println("postEntity = " + postEntity); // request 엔티티 확인

PostEntity savedEntity = postRepository.save(postEntity); // response 엔티티 확인

System.out.println("savedEntity = " + savedEntity); // response 엔티티 확인
PostDto responseDto = toDto(savedEntity); // 저장된 엔티티 를 DTO로 변환해서 return
return responseDto;

} else { // user가 관리자가 아닌 경우
// 공지 생성 불가능 - 접근 권한 없음 (Exception)
throw new HasNoAuthorityException();
}
}
public PostDto updatePost(PostDto postDto, Long userId, Long postId) // 게시글 수정하기
{

Optional<PostEntity> postById = postRepository.findById(postId);
PostEntity postEntity = postById.orElseThrow();
PostEntity postEntity = postById.orElseThrow(PostNotFoundException::new);

// 해당 URL을 요청한 사람이 공지 작성자인 경우에만 수정 가능
// 해당 URL을 요청자 == 공지 작성자 일 때에만 수정 가능
// 수정 목록 : title, content, thumbnail

// DB 내 게시글 작성자 - 요청된 유저 ID 동일 & DB 내 게시글 작성자 - 요청된 게시글 작성자 동일
if(postEntity.getWriter() == userId && postEntity.getWriter() == postDto.getWriter()) {
System.out.println("유저 정보가 일치");
System.out.println("유저 정보 일치");
postEntity.updateContent(postDto);

PostEntity savedEntity = postRepository.save(postEntity);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package JWTLogIn.JWT.user.exception;

import JWTLogIn.JWT.common.exception.CommonException;

public class HasNoAuthorityException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package JWTLogIn.JWT.user.exception;

import JWTLogIn.JWT.common.exception.CommonException;

public class UserNotFoundException extends CommonException {
}

0 comments on commit 548f67b

Please sign in to comment.