-
Notifications
You must be signed in to change notification settings - Fork 0
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
[feat] 3차 세미나 과제 코드입니다. #6
Open
choyeongju
wants to merge
1
commit into
main
Choose a base branch
from
week/3
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
13 changes: 13 additions & 0 deletions
13
homework3/src/main/java/org/sopt/homework3/Homework3Application.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.sopt.homework3; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
||
@SpringBootApplication | ||
public class Homework3Application { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(Homework3Application.class, args); | ||
} | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
homework3/src/main/java/org/sopt/homework3/common/GlobalExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.sopt.homework3.common; | ||
|
||
|
||
import jakarta.persistence.EntityNotFoundException; | ||
import org.sopt.homework3.common.dto.ErrorResponse; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.MethodArgumentNotValidException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
import java.util.Objects; | ||
|
||
|
||
@RestControllerAdvice | ||
public class GlobalExceptionHandler { | ||
|
||
@ExceptionHandler(EntityNotFoundException.class) | ||
protected ResponseEntity<ErrorResponse> handleEntityNotFoundException(EntityNotFoundException e) { | ||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ErrorResponse.of(HttpStatus.NOT_FOUND.value(), e.getMessage())); | ||
} | ||
@ExceptionHandler(MethodArgumentNotValidException.class) | ||
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { | ||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage())); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
homework3/src/main/java/org/sopt/homework3/common/dto/ErrorMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.sopt.homework3.common.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public enum ErrorMessage { | ||
MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "ID에 해당하는 사용자가 존재하지 않습니다."), | ||
BLOG_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "ID에 해당하는 블로그가 없습니다."), | ||
NON_MEMBER(HttpStatus.NOT_EXTENDED.value(), "블로그 소유자가 아니므로 권한이 없습니다."), | ||
POST_NOT_FOUND(HttpStatus.NOT_EXTENDED.value(), "아이디에 해당하는 블로그의 포스트가 없습니다.") | ||
; | ||
private final int status; | ||
private final String message; | ||
} |
13 changes: 13 additions & 0 deletions
13
homework3/src/main/java/org/sopt/homework3/common/dto/ErrorResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.sopt.homework3.common.dto; | ||
|
||
public record ErrorResponse( | ||
int status, | ||
String message | ||
) { | ||
public static ErrorResponse of(int status, String message) { | ||
return new ErrorResponse(status, message); | ||
} | ||
public static ErrorResponse of(ErrorMessage errorMessage) { | ||
return new ErrorResponse(errorMessage.getStatus(), errorMessage.getMessage()); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
homework3/src/main/java/org/sopt/homework3/common/dto/SuccessMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.sopt.homework3.common.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public enum SuccessMessage{ | ||
|
||
BLOG_CREATE_SUCCESS(HttpStatus.CREATED.value(), "블로그 생성이 완료되었습니다."), | ||
BLOG_POST_CREATE_SUCCESS(HttpStatus.CREATED.value(), "블로그 글이 작성되었습니다."), | ||
BLOG_POST_GET_SUCCESS(HttpStatus.CREATED.value(),"블로그 글을 성공적으로 가져왔습니다."), | ||
BLOG_POST_NOT_FOUND(HttpStatus.NOT_FOUND.value(),"블로그 글을 찾을 수 없습니다.") | ||
|
||
; | ||
private final int status; | ||
private final String message; | ||
} |
16 changes: 16 additions & 0 deletions
16
homework3/src/main/java/org/sopt/homework3/common/dto/SuccessStatusResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.sopt.homework3.common.dto; | ||
|
||
|
||
public record SuccessStatusResponse<T>( | ||
int status, | ||
String message, | ||
T data | ||
) { | ||
public static SuccessStatusResponse<Void> of(SuccessMessage successMessage) { | ||
return new SuccessStatusResponse<>(successMessage.getStatus(), successMessage.getMessage(), null); | ||
} | ||
|
||
public static <T> SuccessStatusResponse<T> of(SuccessMessage successMessage, T data) { | ||
return new SuccessStatusResponse<>(successMessage.getStatus(), successMessage.getMessage(), data); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
homework3/src/main/java/org/sopt/homework3/config/JpaAuditingConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.sopt.homework3.config; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing; | ||
|
||
/* | ||
Auditing 기능을 통해, 엔티티 생성되고 변경되는 시점 감지해서 | ||
생성시각/수정시각/생성한 사람/수정한 사람 기록 가능 | ||
*/ | ||
@Configuration | ||
@EnableJpaAuditing //JPA가 엔티티를 감시할 수 있게 해줌 | ||
public class JpaAuditingConfig { | ||
} |
83 changes: 83 additions & 0 deletions
83
homework3/src/main/java/org/sopt/homework3/controller/BlogController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package org.sopt.homework3.controller; | ||
|
||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.sopt.homework3.common.dto.ErrorMessage; | ||
import org.sopt.homework3.common.dto.SuccessMessage; | ||
import org.sopt.homework3.common.dto.SuccessStatusResponse; | ||
import org.sopt.homework3.domain.Blog; | ||
import org.sopt.homework3.domain.Post; | ||
import org.sopt.homework3.exception.CustomizedException; | ||
import org.sopt.homework3.exception.NotFoundException; | ||
import org.sopt.homework3.repository.BlogRepository; | ||
import org.sopt.homework3.service.BlogService; | ||
import org.sopt.homework3.service.dto.BlogCreateRequest; | ||
import org.sopt.homework3.service.dto.BlogPostGetRequest; | ||
import org.sopt.homework3.service.dto.BlogTitleUpdateRequest; | ||
import org.sopt.homework3.service.dto.BlogWriteRequest; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@RestController | ||
@RequestMapping("/api/v1") | ||
@RequiredArgsConstructor | ||
public class BlogController { | ||
|
||
private final BlogService blogService; | ||
private final BlogRepository blogRepository; | ||
|
||
@PostMapping("/blog") | ||
public ResponseEntity<SuccessStatusResponse> createBlog( | ||
@RequestHeader(name = "memberId") Long memberId, | ||
@RequestBody BlogCreateRequest blogCreateRequest | ||
) { | ||
return ResponseEntity.status(HttpStatus.CREATED).header( | ||
"Location", | ||
blogService.create(memberId, blogCreateRequest)) | ||
.body(SuccessStatusResponse.of(SuccessMessage.BLOG_CREATE_SUCCESS)); | ||
} | ||
|
||
@PatchMapping("/blog/{blogId}/title") | ||
public ResponseEntity updateBlogTitle( | ||
@PathVariable Long blogId, | ||
@Valid @RequestBody BlogTitleUpdateRequest blogTitleUpdateRequest | ||
) { | ||
blogService.updateTitle(blogId, blogTitleUpdateRequest); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
|
||
//여기서부터 숙제 코드 | ||
@PostMapping("/blog/{blogId}/post") //글쓰기 | ||
public ResponseEntity<SuccessStatusResponse> writeBlogPost( | ||
@PathVariable Long blogId, | ||
@RequestHeader(name = "memberId") Long memberId, | ||
@Valid @RequestBody BlogWriteRequest blogWriteRequest | ||
) { | ||
blogService.validateMember(blogId, memberId); //블로그 소유자인지 확인 | ||
blogService.writePost(blogId, memberId, blogWriteRequest); | ||
return ResponseEntity.status(HttpStatus.CREATED) | ||
.body(SuccessStatusResponse.of(SuccessMessage.BLOG_POST_CREATE_SUCCESS)); | ||
} | ||
|
||
@DeleteMapping("/blog/{blogId}") //블로그 삭제 | ||
public ResponseEntity<Void> deleteBlog(@PathVariable Long blogId) { | ||
blogService.deleteBlog(blogId); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
|
||
@GetMapping("/blog/{blogId}") | ||
public ResponseEntity<List<BlogPostGetRequest>> findPostsByBlogId( | ||
@PathVariable Long blogId, | ||
@RequestHeader(name = "memberId") Long memberId | ||
){ | ||
Blog blog = blogService.getPostById(blogId, blogId); | ||
List<BlogPostGetRequest> blogPostGetRequests = blog.getPosts().stream() | ||
.map(BlogPostGetRequest::of) | ||
.collect(Collectors.toList()); | ||
return ResponseEntity.ok(blogPostGetRequests); | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
homework3/src/main/java/org/sopt/homework3/controller/MemberController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package org.sopt.homework3.controller; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.sopt.homework3.service.MemberService; | ||
import org.sopt.homework3.service.dto.MemberCreateDto; | ||
import org.sopt.homework3.service.dto.MemberFindDto; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.net.URI; | ||
|
||
@Transactional | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/v1/member") //어디로 요청이 들어올거냐?를 보는 것. | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
@PostMapping | ||
public ResponseEntity postMember(@RequestBody MemberCreateDto memberCreate) { | ||
return ResponseEntity.created(URI.create(memberService.createMember(memberCreate))).build(); | ||
//createMember가 MemberService의 함수이다. | ||
} | ||
|
||
@GetMapping("/{memberId}") | ||
public ResponseEntity<MemberFindDto> findMemberById(@PathVariable Long memberId){ | ||
return ResponseEntity.ok(memberService.findMemberById(memberId)); | ||
//findMemberById가 MemberService의 함수이다. | ||
} | ||
|
||
@DeleteMapping("/{memberId}") | ||
public ResponseEntity deleteMember(@PathVariable Long memberId){ | ||
memberService.deleteMemberById(memberId); //deleteMemberById가 MemberService의 함수이다. | ||
|
||
return ResponseEntity.noContent().build(); | ||
/* | ||
클라이언트에게 반환할 데이터가 없으므로, HTTP 상태 코드 204(No Content)를 함께 응답합니다. | ||
이는 요청이 성공적으로 처리되었지만 응답으로 반환할 데이터가 없음을 나타냅니다. | ||
*/ | ||
|
||
} | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
homework3/src/main/java/org/sopt/homework3/controller/TestController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.sopt.homework3.controller; | ||
|
||
import org.sopt.homework3.controller.dto.ApiResponse; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
/* | ||
* 이 컨트롤러는 /test 경로로 들어오는 GET 요청에는 "test API" 문자열을 반환하고, | ||
* /test/json 경로로 들어오는 GET 요청에는 JSON 형식의 응답을 반환 | ||
*/ | ||
|
||
@RestController | ||
@RequestMapping("/test") | ||
public class TestController { | ||
|
||
@GetMapping | ||
public String test(){ | ||
return "test API"; | ||
} | ||
|
||
@GetMapping("/json") | ||
public ApiResponse testJson(){ | ||
return ApiResponse.create("test API with JSON"); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
homework3/src/main/java/org/sopt/homework3/controller/dto/ApiResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.sopt.homework3.controller.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
|
||
/* | ||
JSON 통신을 해야 하므로, 이 클래스를 활용하여 JSON 객체를 만드는 것이다. | ||
리스폰스 객체의 필드에 접근해야하기 때문에 @Getter 어노테이션이 없으면 통신이 되지 않음. | ||
*/ | ||
@AllArgsConstructor //생성자 자동으로 생성해줌 | ||
@Getter | ||
public class ApiResponse { | ||
private String content; | ||
|
||
public static ApiResponse create(String content){ | ||
return new ApiResponse(content); | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
homework3/src/main/java/org/sopt/homework3/domain/BaseTimeEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.sopt.homework3.domain; | ||
|
||
import jakarta.persistence.EntityListeners; | ||
import jakarta.persistence.MappedSuperclass; | ||
import org.springframework.data.annotation.CreatedDate; | ||
import org.springframework.data.annotation.LastModifiedDate; | ||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
|
||
@MappedSuperclass | ||
@EntityListeners(AuditingEntityListener.class) | ||
public abstract class BaseTimeEntity{ | ||
|
||
@CreatedDate | ||
private LocalDateTime createAt; | ||
|
||
@LastModifiedDate | ||
private LocalDateTime updateAt; | ||
} |
52 changes: 52 additions & 0 deletions
52
homework3/src/main/java/org/sopt/homework3/domain/Blog.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package org.sopt.homework3.domain; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.sopt.homework3.service.dto.BlogCreateRequest; | ||
import org.sopt.homework3.service.dto.BlogTitleUpdateRequest; | ||
import org.sopt.homework3.service.dto.BlogWriteRequest; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Entity | ||
@Getter | ||
@NoArgsConstructor | ||
public class Blog extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@OneToOne(fetch = FetchType.LAZY) | ||
private Member member; | ||
|
||
@Column(length = 200) | ||
private String title; | ||
|
||
private String description; | ||
|
||
private Blog(Member member, String title, String description) { | ||
this.member = member; | ||
this.title = title; | ||
this.description = description; | ||
} | ||
|
||
public static Blog create(Member member, BlogCreateRequest blogCreateRequest) { | ||
return new Blog(member, blogCreateRequest.title(), blogCreateRequest.description()); | ||
} | ||
|
||
public void updateTitle(BlogTitleUpdateRequest blogTitleUpdateRequest) { | ||
this.title = blogTitleUpdateRequest.title(); | ||
} | ||
|
||
//여기서부터 숙제코드 | ||
@OneToMany(mappedBy = "blog", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) | ||
private List<Post> posts = new ArrayList<>(); | ||
|
||
public void addPost(Member member, BlogWriteRequest blogWriteRequest) { | ||
Post newPost = new Post(this, blogWriteRequest.title(), blogWriteRequest.contents(), member); | ||
this.posts.add(newPost); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FetchType을 Eager로 설정한 이유가 있을까요!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다시 한 번 복습하다 보니 fetch = FetchType.LAZY 로 설정하는 것이 좋겠다는 것을 알게되었네요..! 감사합니다아~!