Skip to content

Commit

Permalink
Merge pull request #6 from TG-WinG/feature/blog
Browse files Browse the repository at this point in the history
Feature/blog
  • Loading branch information
3un0ia authored May 20, 2024
2 parents a30710c + 3fba222 commit 8192cda
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 59 deletions.
46 changes: 27 additions & 19 deletions src/main/java/kr/tgwing/tech/blog/controller/PostController.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package kr.tgwing.tech.blog.controller;

import kr.tgwing.tech.blog.dto.PostDto;
import kr.tgwing.tech.blog.exception.PathHasNoPostIdException;
import kr.tgwing.tech.blog.service.PostServiceImpl;
import kr.tgwing.tech.security.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.Optional;

@RestController
@RequestMapping("/admin")
@RequiredArgsConstructor
public class PostController {

Expand All @@ -26,11 +30,10 @@ public class PostController {

@GetMapping("/blog") // 블로그 전체 가져오기 - GET, /tgwing.kr/notice
public ResponseEntity<Page> getAllPostswithSearch(@RequestParam(value = "text", required = false) String text,
@RequestParam int page,
@PageableDefault Pageable pageable) {
@PageableDefault Pageable pageable) {
System.out.println("-- Retrieve All of Posts --");

Page<PostDto> postsInPage = postService.getPostsInPage(text, page, pageable);
Page<PostDto> postsInPage = postService.getPostsInPage(text, pageable);

return ResponseEntity.ok(postsInPage);
}
Expand All @@ -47,50 +50,55 @@ public ResponseEntity<Page> getAllPostswithSearch(@RequestParam(value = "text",
// }

@GetMapping("/blog/{postId}") // 특정 블로그 가져오기 - GET, /tgwing.kr/blog/{postId}
public ResponseEntity<PostDto> getPost(@PathVariable("postId") Long postId) {
public ResponseEntity<PostDto> getPost(@PathVariable(required = false, name = "postId") Optional<Long> optional) {
System.out.println("-- Retreive Specific Post by Id --");
// 특정 게시글 id에 대한 post 정보를 모아 반환 (id, title, description, writtenDate, ?조회수?
// 특정 게시글 id에 대한 post 정보를 모아 반환

Long postId = optional.orElseThrow(PathHasNoPostIdException::new);

PostDto post = postService.getPost(postId);
return ResponseEntity.ok(post);
}

@PostMapping("/blog/post") // 블로그 작성 - POST, /tgwing.kr/blog/post
@PostMapping("/blog") // 블로그 작성 - POST, /tgwing.kr/blog/post
public ResponseEntity<PostDto> post(@RequestBody PostDto requestDto,
@RequestHeader("authorization") String token)
Principal principal)
{
System.out.println("-- Post new post --");
System.out.println("Request Dto = " + requestDto);
// RequestDTO : writer, title, content, thumbnailUri

PostDto responseDto = postService.createPost(requestDto, token);
String utilStudentId = principal.getName();

PostDto responseDto = postService.createPost(requestDto, utilStudentId);
return ResponseEntity.ok(responseDto);
}
// @CrossOrigin
@PutMapping ("/blog/modify/{id}") // 블로그 수정 - PUT, /tgwing.kr/blog/modify/{id}
@PutMapping ("/blog/{postId}") // 블로그 수정 - PUT, /tgwing.kr/blog/modify/{id}
public ResponseEntity<PostDto> modify(@RequestBody PostDto requestDto,
@RequestHeader("authorization") String token,
@RequestParam Long userId,
@PathVariable("id") Long id)
@PathVariable Long postId,
Principal principal)
{
System.out.println("-- Modify (title + content) of post --");
// repository에 대해서 해당 id를 가진 엔티티를 가져오고,
// 그 엔티티의 내용을 dto 내용으로 수정 및 다시 repository에 저장한다

System.out.println("Request Dto = " + requestDto);

PostDto responseDto = postService.updatePost(requestDto, userId, id, token);
String utilStudentId = principal.getName();
PostDto responseDto = postService.updatePost(requestDto, postId, utilStudentId);

return ResponseEntity.ok(responseDto);
}

@DeleteMapping("/blog/delete/{id}") // 블로그 삭제 - DELETE, /tgwing.kr/blog/delete/{id}
public ResponseEntity<Void> delete(@PathVariable("id") Long postId,
@RequestParam Long userId)
@DeleteMapping("/blog/{postId}") // 블로그 삭제 - DELETE, /tgwing.kr/blog/delete/{id}
public ResponseEntity<Void> delete(@PathVariable Long postId,
Principal principal)
{
System.out.println("-- Delete Specific Post --");
// 아이디에 해당하는 글 객체를 그냥 삭제 -> 응답
postService.deletePost(userId, postId);

String utilStudentId = principal.getName();
postService.deletePost(postId, utilStudentId);
return ResponseEntity.noContent().build();
}
}
1 change: 1 addition & 0 deletions src/main/java/kr/tgwing/tech/blog/dto/PostDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@Builder
@AllArgsConstructor
public class PostDto {
private Long id;
private Long writer;
private String title;
private String content;
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/kr/tgwing/tech/blog/entity/PostEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@ public class PostEntity extends BaseEntity {

public static PostDto toDto(PostEntity postEntity) {
return PostDto.builder()
.id(postEntity.id)
.writer(postEntity.writer)
.title(postEntity.title)
.content(postEntity.content)
.thumbnail(postEntity.thumbnail).build();
}

// public void updateContent(PostDto postDto) {
// this.title = postDto.getTitle();
// this.content = postDto.getContent();
// this.thumbnail = postDto.getThumbnail();
// }
public void updateContent(PostDto postDto) {
this.title = postDto.getTitle();
this.content = postDto.getContent();
this.thumbnail = postDto.getThumbnail();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.tgwing.tech.blog.exception;

import kr.tgwing.tech.common.exception.CommonException;

public class InappropriateUserPostRelationException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.tgwing.tech.blog.exception;

import kr.tgwing.tech.common.exception.CommonException;

public class PageExceededDataException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.tgwing.tech.blog.exception;

import kr.tgwing.tech.common.exception.CommonException;

public class PathHasNoPostIdException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.tgwing.tech.blog.exception;

import kr.tgwing.tech.common.exception.CommonException;

public class PostNotFoundException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.tgwing.tech.blog.exception;

import kr.tgwing.tech.common.exception.CommonException;

public class UserIsNotPostWriterException extends CommonException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.tgwing.tech.blog.exception;

import kr.tgwing.tech.common.exception.CommonException;

public class WrongPostRequestException extends CommonException {
}
6 changes: 3 additions & 3 deletions src/main/java/kr/tgwing/tech/blog/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public interface PostService {
public PostDto getPost(Long postId);
public PostDto createPost(PostDto requestDto, String token);
public PostDto updatePost(PostDto postDto, Long userId, Long postId, String token);
public void deletePost(Long userId, Long postId);
public Page<PostDto> getPostsInPage(String text, int page, Pageable pageable);
public PostDto updatePost(PostDto postDto, Long postId, String utilStudentId);
public void deletePost(Long postId, String utilStudentId);
public Page<PostDto> getPostsInPage(String text, Pageable pageable);
}
79 changes: 47 additions & 32 deletions src/main/java/kr/tgwing/tech/blog/service/PostServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@

import kr.tgwing.tech.blog.dto.PostDto;
import kr.tgwing.tech.blog.entity.PostEntity;
import kr.tgwing.tech.blog.exception.PostNotFoundException;
import kr.tgwing.tech.blog.exception.UserIsNotPostWriterException;
import kr.tgwing.tech.blog.exception.WrongPostRequestException;
import kr.tgwing.tech.blog.repository.PostRepository;
import kr.tgwing.tech.user.entity.UserEntity;
import kr.tgwing.tech.user.exception.UserNotFoundException;
import kr.tgwing.tech.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

Expand All @@ -24,18 +30,17 @@
@Service
@Transactional
@RequiredArgsConstructor
@Slf4j
public class PostServiceImpl implements PostService {
private final PostRepository postRepository;
// private final UserRepository userRepository;
// private final AuthService authService;
private final UserRepository userRepository;

@Override
public PostDto getPost(Long postId) // 특정 게시글 가져오기
{
// 입력된 postId에 해당하는 글 찾기
Optional<PostEntity> postEntityInOp = postRepository.findById(postId);
// PostEntity postEntity = postEntityInOp.orElseThrow(PostNotFoundException::new); 예외처리 생략
PostEntity postEntity = postEntityInOp.orElseThrow();
PostEntity postEntity = postEntityInOp.orElseThrow(PostNotFoundException::new);

return toDto(postEntity);
}
Expand All @@ -50,15 +55,17 @@ private Page<PostEntity> getAllPosts(PageRequest pageRequest) { // 모든 공지
}

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

String jwt = token.split(" ")[1];
// String studentId = authService.extractStudentId(jwt);
// 현재 사용자와 요청 시 들어온 writer가 같은지 확인
if (!Objects.equals(userEntity.getStudentId(), utilStudentId)) {
throw new WrongPostRequestException();
}

// entity에는 저장된 썸네일의 uri만 추가로 넣어서 저장
PostEntity postEntity = toEntity(requestDto);
Expand All @@ -68,47 +75,55 @@ public PostDto createPost(PostDto requestDto, String token) // 공지 생성하
}

@Override
public PostDto updatePost(PostDto postDto, Long userId, Long postId, String token) // 게시글 수정하기
public PostDto updatePost(PostDto postDto, Long postId, String utilStudentId) // 게시글 수정하기
{
Optional<PostEntity> postById = postRepository.findById(postId);
// PostEntity postEntity = postById.orElseThrow(PostNotFoundException::new);
PostEntity postEntity = postById.orElseThrow();

String jwt = token.split(" ")[1];
PostEntity postEntity = postById.orElseThrow(PostNotFoundException::new);

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

Optional<UserEntity> userById = userRepository.findById(postEntity.getWriter());
UserEntity userEntity = userById.orElseThrow(UserNotFoundException::new); // 유저 notfound 예외처리

log.info("util학번 = {}", utilStudentId);
log.info("user학번 = {}", userEntity.getStudentId());

// DB 내 게시글 작성자 - 요청된 유저 ID 동일 & DB 내 게시글 작성자 - 요청된 게시글 작성자 동일
if(postEntity.getWriter() == userId && postEntity.getWriter() == postDto.getWriter()) {
System.out.println("유저 정보 일치");
// postEntity.updateContent(postDto); // 수정 요
if(Objects.equals(userEntity.getStudentId(), utilStudentId)) {
log.info("학번 일치 - 작성자 확인");
postEntity.updateContent(postDto); // entity 정보 수정

PostEntity savedEntity = postRepository.save(postEntity);
return toDto(savedEntity);
}
else { // 공지 작성자가 아닌 경우 -- 수정 불가능
System.out.println("유저 정보 불일치 - 작성자가 아니므로 수정 불가능");
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
log.info("학번 불일치 - 작성자가 아니므로 수정 불가능");
throw new UserIsNotPostWriterException();
}
}
@Override
public void deletePost(Long userId, Long postId) // 게시글 삭제하기
public void deletePost(Long postId, String utilStudentId) // 게시글 삭제하기
{
Optional<PostEntity> postById = postRepository.findById(postId);
PostEntity postEntity = postById.orElseThrow();
PostEntity postEntity = postById.orElseThrow(PostNotFoundException::new);

Optional<UserEntity> userById = userRepository.findById(postEntity.getWriter());
UserEntity userEntity = userById.orElseThrow(UserNotFoundException::new);

// 해당 URL을 요청한 사람이 공지 작성자인 경우에만 삭제 가능
if(postEntity.getWriter() == userId) {
if(Objects.equals(userEntity.getStudentId(), utilStudentId)) {
log.info("학번 일치 - 작성자 확인");
postRepository.deleteById(postId);
} else {
System.out.println("삭제 불가 - 작성자가 아님");
throw new ResponseStatusException(HttpStatus.FORBIDDEN); }
log.info("학번 불일치 - 작성자가 아니므로 삭제 불가능");
throw new UserIsNotPostWriterException(); }
}

@Override
public Page<PostDto> getPostsInPage(String text, int page, Pageable pageable) {
public Page<PostDto> getPostsInPage(String text, Pageable pageable) {
int size = pageable.getPageSize();
int page = pageable.getPageNumber();
long total = 0L;
Page<PostEntity> postPage = null;

Expand All @@ -124,23 +139,23 @@ public Page<PostDto> getPostsInPage(String text, int page, Pageable pageable) {
else { // - 파라미터로 검색된 블로그만 걸러서 반환
postPage = searchPosts(text, pageRequest);
total = postRepository.countByTitleContains(text);
System.out.println("total = " + total);
log.info("total = " + total);
}

if(!(total > page * size)) {throw new ResponseStatusException(HttpStatus.BAD_REQUEST); }
if(!(total > page * size)) {throw new WrongPostRequestException(); }
// 이후 ExceptionHandler 정의 필요

if (postPage.isEmpty()) {
System.out.println("조회 불가능");
log.info("page 조회 불가");
}

// stream이 비어있는 경우
postPage.stream().findFirst().orElseThrow(()-> new ResponseStatusException(HttpStatus.NO_CONTENT));
postPage.stream().findFirst().orElseThrow(()-> new PostNotFoundException());

// page가 총 데이터 건수를 초과하는 경우
long totalCount = postPage.getTotalElements();
long requestCount = (postPage.getTotalPages() - 1) * postPage.getSize();
if(!(totalCount > requestCount)) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST); }
if(!(totalCount > requestCount)) { throw new WrongPostRequestException(); }

// Entity -> Dto 변환 - Dto 담은 page 반환
List<PostEntity> posts = postPage.getContent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ protected CommonException(Exception e) {
protected CommonException(String message) {
super(message);
}

protected CommonException(Exception e, String msg) {
super(msg, e);
}
}
13 changes: 13 additions & 0 deletions src/main/java/kr/tgwing/tech/common/exception/ExceptionMapper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package kr.tgwing.tech.common.exception;

import kr.tgwing.tech.blog.exception.*;
import kr.tgwing.tech.user.exception.*;
import org.springframework.http.HttpStatus;

Expand Down Expand Up @@ -30,6 +31,18 @@ private static void setUpUserException() {
}

private static void setUpPostException() {
mapper.put(PostNotFoundException.class,
ExceptionSituation.of("해당하는 블로그를 찾을 수 없습니다", HttpStatus.NOT_FOUND, 4400));
mapper.put(PathHasNoPostIdException.class,
ExceptionSituation.of("경로에 적절한 블로그의 id가 필요합니다", HttpStatus.BAD_REQUEST, 4401));
mapper.put(PageExceededDataException.class,
ExceptionSituation.of("데이터 갯수에 초과되는 페이지 수가 입력되었습니다", HttpStatus.BAD_REQUEST, 4402));
mapper.put(InappropriateUserPostRelationException.class,
ExceptionSituation.of("블로그 작성자 정보가 서로 일치하지 않습니다", HttpStatus.CONFLICT, 4403));
mapper.put(UserIsNotPostWriterException.class,
ExceptionSituation.of("블로그 수정(삭제) 권한이 존재하지 않습니다", HttpStatus.FORBIDDEN, 4404));
mapper.put(WrongPostRequestException.class,
ExceptionSituation.of("요청에 잘못된 정보가 포함되어 있습니다", HttpStatus.BAD_REQUEST, 4406));
}


Expand Down

0 comments on commit 8192cda

Please sign in to comment.