From a3d753c6dc4ec8f7e32c8d73009b0a1e91764dfc Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 02:23:38 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat(entity)=20Entity=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{repository => entity}/DiaryEntity.java | 46 +++++++++++-------- .../org/sopt/Diary/entity/UserEntity.java | 25 ++++++++++ .../org/sopt/Diary/repository/Category.java | 2 +- .../Diary/repository/DiaryRepository.java | 3 +- .../org/sopt/Diary/service/DiaryService.java | 2 +- 5 files changed, 55 insertions(+), 23 deletions(-) rename src/main/java/org/sopt/Diary/{repository => entity}/DiaryEntity.java (58%) create mode 100644 src/main/java/org/sopt/Diary/entity/UserEntity.java diff --git a/src/main/java/org/sopt/Diary/repository/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java similarity index 58% rename from src/main/java/org/sopt/Diary/repository/DiaryEntity.java rename to src/main/java/org/sopt/Diary/entity/DiaryEntity.java index c7176c1..03d94b7 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -1,49 +1,56 @@ -package org.sopt.Diary.repository; +package org.sopt.Diary.entity; import jakarta.persistence.*; +import org.sopt.Diary.repository.Category; import java.time.LocalDateTime; @Entity +@Table(name="diary") public class DiaryEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - public Long id; + private Long id; - @Column - public String title; + @Column(name="title") + private String title; - @Column - public String content; + @Column(name="content") + private String content; - @Column + //Column의 기본값은 nullabel = true 이므로 기본 타입을 사용할 경우 nullable = false를 하는게 안전하다 + @Column(name="is_private", nullable = false) + private boolean isPrivate; + + @Column(name="created_at") public LocalDateTime createdAt = LocalDateTime.now(); - @Enumerated(EnumType.STRING) + @Column(name="category") + @Enumerated(EnumType.STRING) //enum 이름 그대로 DB에 저장된다 private Category category; - public DiaryEntity(final Long id, final String title, final String content, final LocalDateTime createdAt, final Category category) { - this. id = id; - this.title = title; + //JPA 는 엔티티 객체를 생성할때 기본 생성자를 사용하므로 반드시 있어야 한다! + public DiaryEntity() {} + + public DiaryEntity(String title, String content,Category category) { + this.title = title; this.content = content; - this.createdAt = createdAt; this.category = category; - } - - public DiaryEntity() { } - public DiaryEntity(String title, String content,Category category) { - this.title = title; + + public DiaryEntity(final Long id, final String title, final String content, final LocalDateTime createdAt, final Category category) { + this. id = id; + this.title = title; this.content = content; + this.createdAt = createdAt; this.category = category; - } public long getId(){ - return id; + return id; } public String getTitle(){ @@ -62,3 +69,4 @@ public Category getCategory(){ } } + diff --git a/src/main/java/org/sopt/Diary/entity/UserEntity.java b/src/main/java/org/sopt/Diary/entity/UserEntity.java new file mode 100644 index 0000000..6d392b8 --- /dev/null +++ b/src/main/java/org/sopt/Diary/entity/UserEntity.java @@ -0,0 +1,25 @@ +package org.sopt.Diary.entity; + +import jakarta.persistence.*; + +@Entity +@Table(name="user") +public class UserEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name="login_id") + private String loginId; + + @Column(name="password") + private String password; + + @Column(name="nickname") + private String nickname; + + //기본 생성자 + public UserEntity(){}; + +} diff --git a/src/main/java/org/sopt/Diary/repository/Category.java b/src/main/java/org/sopt/Diary/repository/Category.java index b8dcae7..212a42e 100644 --- a/src/main/java/org/sopt/Diary/repository/Category.java +++ b/src/main/java/org/sopt/Diary/repository/Category.java @@ -1,6 +1,6 @@ package org.sopt.Diary.repository; public enum Category { - 일상,여행,운동,기념일,독서 + food, school, movie, exercise, all } diff --git a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java index a6cc5e3..98b5373 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java +++ b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java @@ -1,7 +1,6 @@ package org.sopt.Diary.repository; -import org.sopt.Diary.service.Diary; -import org.springframework.data.domain.Sort; +import org.sopt.Diary.entity.DiaryEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index 0c61d36..a50e175 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -3,7 +3,7 @@ import org.sopt.Diary.dto.res.DiariesResponse; import org.sopt.Diary.dto.req.DiaryRequest; import org.sopt.Diary.repository.Category; -import org.sopt.Diary.repository.DiaryEntity; +import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; From eea0f27b0201e68c9f1407be63f4860b05da699f Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 10:41:48 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat(user):=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?,=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../{api => controller}/DiaryController.java | 14 +++--- .../sopt/Diary/controller/UserController.java | 36 +++++++++++++++ .../sopt/Diary/{service => dto}/Diary.java | 4 +- src/main/java/org/sopt/Diary/dto/UserDTO.java | 7 +++ .../java/org/sopt/Diary/dto/req/DiaryReq.java | 9 ++++ .../org/sopt/Diary/dto/req/DiaryRequest.java | 9 ---- .../sopt/Diary/dto/req/DiaryUpdateReq.java | 7 +++ .../Diary/dto/req/DiaryUpdateRequest.java | 7 --- .../org/sopt/Diary/dto/req/SignInReq.java | 6 +++ .../org/sopt/Diary/dto/req/SignUpReq.java | 9 ++++ .../org/sopt/Diary/dto/res/DiaryResponse.java | 2 +- .../org/sopt/Diary/dto/res/UserResponse.java | 16 +++++++ .../{repository => entity}/Category.java | 2 +- .../org/sopt/Diary/entity/DiaryEntity.java | 1 - .../org/sopt/Diary/entity/UserEntity.java | 19 +++++++- .../Diary/repository/DiaryRepository.java | 1 + .../sopt/Diary/repository/UserRepository.java | 11 +++++ .../org/sopt/Diary/service/DiaryService.java | 7 +-- .../org/sopt/Diary/service/UserService.java | 46 +++++++++++++++++++ src/main/resources/application.yml | 13 ++---- 21 files changed, 187 insertions(+), 41 deletions(-) rename src/main/java/org/sopt/Diary/{api => controller}/DiaryController.java (91%) create mode 100644 src/main/java/org/sopt/Diary/controller/UserController.java rename src/main/java/org/sopt/Diary/{service => dto}/Diary.java (93%) create mode 100644 src/main/java/org/sopt/Diary/dto/UserDTO.java create mode 100644 src/main/java/org/sopt/Diary/dto/req/DiaryReq.java delete mode 100644 src/main/java/org/sopt/Diary/dto/req/DiaryRequest.java create mode 100644 src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java delete mode 100644 src/main/java/org/sopt/Diary/dto/req/DiaryUpdateRequest.java create mode 100644 src/main/java/org/sopt/Diary/dto/req/SignInReq.java create mode 100644 src/main/java/org/sopt/Diary/dto/req/SignUpReq.java create mode 100644 src/main/java/org/sopt/Diary/dto/res/UserResponse.java rename src/main/java/org/sopt/Diary/{repository => entity}/Category.java (65%) create mode 100644 src/main/java/org/sopt/Diary/repository/UserRepository.java create mode 100644 src/main/java/org/sopt/Diary/service/UserService.java diff --git a/build.gradle b/build.gradle index 4f66c9f..457689a 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.junit.platform:junit-platform-launcher' - + implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.h2database:h2' runtimeOnly 'mysql:mysql-connector-java:8.0.32' diff --git a/src/main/java/org/sopt/Diary/api/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java similarity index 91% rename from src/main/java/org/sopt/Diary/api/DiaryController.java rename to src/main/java/org/sopt/Diary/controller/DiaryController.java index 6543605..dbfc50b 100644 --- a/src/main/java/org/sopt/Diary/api/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -1,11 +1,11 @@ -package org.sopt.Diary.api; +package org.sopt.Diary.controller; -import org.sopt.Diary.dto.req.DiaryUpdateRequest; +import org.sopt.Diary.dto.req.DiaryUpdateReq; import org.sopt.Diary.dto.res.DiariesResponse; -import org.sopt.Diary.dto.req.DiaryRequest; +import org.sopt.Diary.dto.req.DiaryReq; import org.sopt.Diary.dto.res.DiaryResponse; -import org.sopt.Diary.repository.Category; -import org.sopt.Diary.service.Diary; +import org.sopt.Diary.entity.Category; +import org.sopt.Diary.dto.Diary; import org.sopt.Diary.service.DiaryService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -25,7 +25,7 @@ public DiaryController(DiaryService diaryService) { private final static int LENGTH_LIMIT = 30; @PostMapping("/diary") - ResponseEntity postDiary(@RequestBody final DiaryRequest diaryRequest) { + ResponseEntity postDiary(@RequestBody final DiaryReq diaryRequest) { //final 을 붙여서 매개변수의 재할당을 막음!! if(diaryRequest.content().length()>LENGTH_LIMIT){ @@ -76,7 +76,7 @@ ResponseEntity getDiary(@PathVariable(name = "id") final Long id) } @PatchMapping("/diary/{id}") - ResponseEntity updateDiary(@PathVariable(name = "id") final Long id, @RequestBody DiaryUpdateRequest diaryRequest){ + ResponseEntity updateDiary(@PathVariable(name = "id") final Long id, @RequestBody DiaryUpdateReq diaryRequest){ if (diaryRequest.content().length() > LENGTH_LIMIT) { return ResponseEntity.badRequest().body("글자 수는 30자를 넘을 수 없습니다"); diff --git a/src/main/java/org/sopt/Diary/controller/UserController.java b/src/main/java/org/sopt/Diary/controller/UserController.java new file mode 100644 index 0000000..a0d1cea --- /dev/null +++ b/src/main/java/org/sopt/Diary/controller/UserController.java @@ -0,0 +1,36 @@ +package org.sopt.Diary.controller; + +import jakarta.validation.Valid; +import org.sopt.Diary.dto.req.SignInReq; +import org.sopt.Diary.dto.req.SignUpReq; +import org.sopt.Diary.dto.res.UserResponse; +import org.sopt.Diary.service.UserService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/users") +public class UserController { + + private final UserService userService; + + public UserController(final UserService userService){this.userService=userService;} + + @PostMapping("/signup") + private void signUp(@Valid @RequestBody SignUpReq signUpRequest){ + // 제약사항 따로 없음 + //@Valid 를 통해 RequestBody @NotNull 체크해줌 + userService.join(signUpRequest); + } + + @PostMapping("/signin") + private UserResponse signIn(@Valid @RequestBody SignInReq signInReq){ + Long userId= userService.login(signInReq); + return new UserResponse(userId); + + } + + +} diff --git a/src/main/java/org/sopt/Diary/service/Diary.java b/src/main/java/org/sopt/Diary/dto/Diary.java similarity index 93% rename from src/main/java/org/sopt/Diary/service/Diary.java rename to src/main/java/org/sopt/Diary/dto/Diary.java index 5354e84..9594c6e 100644 --- a/src/main/java/org/sopt/Diary/service/Diary.java +++ b/src/main/java/org/sopt/Diary/dto/Diary.java @@ -1,6 +1,6 @@ -package org.sopt.Diary.service; +package org.sopt.Diary.dto; -import org.sopt.Diary.repository.Category; +import org.sopt.Diary.entity.Category; public class Diary { private long id; diff --git a/src/main/java/org/sopt/Diary/dto/UserDTO.java b/src/main/java/org/sopt/Diary/dto/UserDTO.java new file mode 100644 index 0000000..51adedf --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/UserDTO.java @@ -0,0 +1,7 @@ +package org.sopt.Diary.dto; + +public record UserDTO ( Long id, + String loginId, + String nickname){ + +} diff --git a/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java b/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java new file mode 100644 index 0000000..3ba637c --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java @@ -0,0 +1,9 @@ +package org.sopt.Diary.dto.req; + + +import org.sopt.Diary.entity.Category; + +public record DiaryReq(String title, + String content, + Category category){ +} diff --git a/src/main/java/org/sopt/Diary/dto/req/DiaryRequest.java b/src/main/java/org/sopt/Diary/dto/req/DiaryRequest.java deleted file mode 100644 index 14206b5..0000000 --- a/src/main/java/org/sopt/Diary/dto/req/DiaryRequest.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.sopt.Diary.dto.req; - - -import org.sopt.Diary.repository.Category; - -public record DiaryRequest ( String title, - String content, - Category category){ -} diff --git a/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java b/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java new file mode 100644 index 0000000..0a7a0a3 --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java @@ -0,0 +1,7 @@ +package org.sopt.Diary.dto.req; + + +import org.sopt.Diary.entity.Category; + +public record DiaryUpdateReq(String content , Category category) { +} diff --git a/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateRequest.java b/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateRequest.java deleted file mode 100644 index 088e3b6..0000000 --- a/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.sopt.Diary.dto.req; - - -import org.sopt.Diary.repository.Category; - -public record DiaryUpdateRequest( String content , Category category) { -} diff --git a/src/main/java/org/sopt/Diary/dto/req/SignInReq.java b/src/main/java/org/sopt/Diary/dto/req/SignInReq.java new file mode 100644 index 0000000..80ca080 --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/req/SignInReq.java @@ -0,0 +1,6 @@ +package org.sopt.Diary.dto.req; + +import jakarta.validation.constraints.NotNull; + +public record SignInReq (@NotNull String loginId, @NotNull String password){ +} diff --git a/src/main/java/org/sopt/Diary/dto/req/SignUpReq.java b/src/main/java/org/sopt/Diary/dto/req/SignUpReq.java new file mode 100644 index 0000000..d3bedc5 --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/req/SignUpReq.java @@ -0,0 +1,9 @@ +package org.sopt.Diary.dto.req; + +import jakarta.validation.constraints.NotNull; + +//입력값의 Null 검증을 위한 @Valid, @NotNull +public record SignUpReq ( @NotNull String loginId, @NotNull String password, @NotNull String nickname ) +{ + +} \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java b/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java index fde65d0..76773af 100644 --- a/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java +++ b/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java @@ -1,6 +1,6 @@ package org.sopt.Diary.dto.res; -import org.sopt.Diary.repository.Category; +import org.sopt.Diary.entity.Category; public record DiaryResponse(long id, String title, String content, String createdAt, Category category) { } \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/dto/res/UserResponse.java b/src/main/java/org/sopt/Diary/dto/res/UserResponse.java new file mode 100644 index 0000000..bc20b35 --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/res/UserResponse.java @@ -0,0 +1,16 @@ +package org.sopt.Diary.dto.res; + +public class UserResponse { + + private long userId; + + public UserResponse(long userId){ + this.userId = userId; + } + + public long getUserId(){ + return userId; + } + +} + diff --git a/src/main/java/org/sopt/Diary/repository/Category.java b/src/main/java/org/sopt/Diary/entity/Category.java similarity index 65% rename from src/main/java/org/sopt/Diary/repository/Category.java rename to src/main/java/org/sopt/Diary/entity/Category.java index 212a42e..9790bc4 100644 --- a/src/main/java/org/sopt/Diary/repository/Category.java +++ b/src/main/java/org/sopt/Diary/entity/Category.java @@ -1,4 +1,4 @@ -package org.sopt.Diary.repository; +package org.sopt.Diary.entity; public enum Category { food, school, movie, exercise, all diff --git a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java index 03d94b7..0c4045c 100644 --- a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -1,7 +1,6 @@ package org.sopt.Diary.entity; import jakarta.persistence.*; -import org.sopt.Diary.repository.Category; import java.time.LocalDateTime; diff --git a/src/main/java/org/sopt/Diary/entity/UserEntity.java b/src/main/java/org/sopt/Diary/entity/UserEntity.java index 6d392b8..22140a3 100644 --- a/src/main/java/org/sopt/Diary/entity/UserEntity.java +++ b/src/main/java/org/sopt/Diary/entity/UserEntity.java @@ -1,6 +1,7 @@ package org.sopt.Diary.entity; import jakarta.persistence.*; +import org.sopt.Diary.dto.UserDTO; @Entity @Table(name="user") @@ -8,7 +9,7 @@ public class UserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private long id; @Column(name="login_id") private String loginId; @@ -22,4 +23,20 @@ public class UserEntity { //기본 생성자 public UserEntity(){}; + public UserEntity(final String loginId,final String password, final String nickname){ + this.loginId =loginId; + this.password=password; + this.nickname=nickname; + } + + public static UserEntity createUser(final String loginId,final String password, final String nickname){ + return new UserEntity(loginId, password, nickname); + } + + public long getId(){ + return this.id; + } + + + } diff --git a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java index 98b5373..16b582a 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java +++ b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java @@ -1,5 +1,6 @@ package org.sopt.Diary.repository; +import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/org/sopt/Diary/repository/UserRepository.java b/src/main/java/org/sopt/Diary/repository/UserRepository.java new file mode 100644 index 0000000..a3a9cef --- /dev/null +++ b/src/main/java/org/sopt/Diary/repository/UserRepository.java @@ -0,0 +1,11 @@ +package org.sopt.Diary.repository; + +import org.sopt.Diary.entity.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + Optional findByLoginIdAndPassword(String loginId, String password); +} diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index a50e175..e177154 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -1,8 +1,9 @@ package org.sopt.Diary.service; +import org.sopt.Diary.dto.Diary; import org.sopt.Diary.dto.res.DiariesResponse; -import org.sopt.Diary.dto.req.DiaryRequest; -import org.sopt.Diary.repository.Category; +import org.sopt.Diary.dto.req.DiaryReq; +import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; @@ -32,7 +33,7 @@ public void validateTitle(String title){ } } - public void createDiary(DiaryRequest diaryRequest) { + public void createDiary(DiaryReq diaryRequest) { validateTitle(diaryRequest.title()); int minutesSinceLastDiary = calculateMinutesSinceLastDiary(); diff --git a/src/main/java/org/sopt/Diary/service/UserService.java b/src/main/java/org/sopt/Diary/service/UserService.java new file mode 100644 index 0000000..9af3a3f --- /dev/null +++ b/src/main/java/org/sopt/Diary/service/UserService.java @@ -0,0 +1,46 @@ +package org.sopt.Diary.service; + +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; +import org.sopt.Diary.dto.req.SignInReq; +import org.sopt.Diary.dto.req.SignUpReq; + +import org.sopt.Diary.entity.UserEntity; +import org.sopt.Diary.repository.UserRepository; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@Transactional // 클래스의 메소드 호출시 트랜잭션 시작, 메소드 종료시 커밋, 예외 발생시 롤백 +public class UserService { + + private final UserRepository userRepository; + + public UserService(UserRepository userRepository){ + this.userRepository = userRepository;} + + public void join(@Valid final SignUpReq signUpRequest) { + //중복회원 검증 + validateDuplicateMember(signUpRequest.loginId(), signUpRequest.password()); + // SignUpReq -> UserEntity + final UserEntity newUserEntity = UserEntity.createUser(signUpRequest.loginId(), signUpRequest.password(), signUpRequest.nickname()); + userRepository.save(newUserEntity); + } + + private void validateDuplicateMember(final String loginId, final String password) { + Optional findUser = userRepository.findByLoginIdAndPassword(loginId, password); + if(findUser.isPresent()){ + throw new IllegalStateException("이미 존재하는 회원입니다"); + } + } + + public Long login(@Valid final SignInReq signInReq) { + + // 1. userRepository 에서 Id 찾기 -> NPE 방지 위해 Optional 사용 + UserEntity findUser = userRepository.findByLoginIdAndPassword(signInReq.loginId(), signInReq.password()) + .orElseThrow(()-> new IllegalStateException("로그인 정보가 올바르지 않습니다")); + // 2. UserID 반환 + return findUser.getId(); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 012ab38..2c003ff 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,17 +1,14 @@ spring: - h2: - console: - enabled: true datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:testdb + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/seminar3 username: root - password: + password: 12345678 jpa: show-sql: true hibernate: - ddl-auto: create - dialect: org.hibernate.dialect.H2Dialect + ddl-auto: update + dialect: org.hibernate.dialect.MySQL8Dialect properties: format_sql: true show_sql: true \ No newline at end of file From 077e7025439510e2e5d2f760d5d9bdb82dfb9178 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 11:08:09 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat(diary):=EB=8B=A4=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20=EC=88=98=EC=A0=95=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Diary/controller/DiariesController.java | 48 +++++++++++++++++ .../Diary/controller/DiaryController.java | 33 +++--------- .../java/org/sopt/Diary/dto/req/DiaryReq.java | 9 ++-- .../org/sopt/Diary/entity/DiaryEntity.java | 4 +- .../org/sopt/Diary/service/DiaryService.java | 53 ++++++++++++------- .../org/sopt/Diary/service/UserService.java | 5 ++ 6 files changed, 100 insertions(+), 52 deletions(-) create mode 100644 src/main/java/org/sopt/Diary/controller/DiariesController.java diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java new file mode 100644 index 0000000..190ff24 --- /dev/null +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -0,0 +1,48 @@ +package org.sopt.Diary.controller; + +import org.sopt.Diary.dto.res.DiariesResponse; +import org.sopt.Diary.entity.Category; +import org.sopt.Diary.service.DiaryService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RequestMapping("diaries") +@RestController +public class DiariesController { + + private final DiaryService diaryService; + + public DiariesController(DiaryService diaryService) { + this.diaryService = diaryService; + } + + + @GetMapping("/diaries") + public ResponseEntity> getDiaries( + @RequestParam(name = "category", required = false) Category category, + @RequestParam(name = "sortByContentLength",required = false, defaultValue = "false")final Boolean sortByContentLength) { + + + final List diariesResponses; + // 각 조건에 따라 한번만 할당되고 추가로 변경되지 않음을 명확하게 하기 위해 final 사용 + + if (category != null) { + // 카테고리로 정렬 + diariesResponses = diaryService.getDiaryListSortByCategory(category); + } else if (sortByContentLength) { + + // 글자수로 정렬 + diariesResponses = diaryService.getDiaryListSortByContent(); + } else { + //최신순으로 정렬 + diariesResponses = diaryService.getDiaryList(); + } + + return ResponseEntity.ok(diariesResponses); + } +} diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index dbfc50b..54596c4 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -1,5 +1,6 @@ package org.sopt.Diary.controller; +import jakarta.validation.Valid; import org.sopt.Diary.dto.req.DiaryUpdateReq; import org.sopt.Diary.dto.res.DiariesResponse; import org.sopt.Diary.dto.req.DiaryReq; @@ -13,6 +14,7 @@ import java.util.List; +@RequestMapping("/diary") @RestController public class DiaryController { @@ -24,40 +26,17 @@ public DiaryController(DiaryService diaryService) { private final static int LENGTH_LIMIT = 30; - @PostMapping("/diary") - ResponseEntity postDiary(@RequestBody final DiaryReq diaryRequest) { - //final 을 붙여서 매개변수의 재할당을 막음!! + @PostMapping() + ResponseEntity postDiary(@RequestHeader("userId") Long userId, @Valid @RequestBody final DiaryReq diaryRequest) { if(diaryRequest.content().length()>LENGTH_LIMIT){ return ResponseEntity.badRequest().body("글자 수는 30자를 넘을 수 없습니다"); } - diaryService.createDiary(diaryRequest); + + diaryService.createDiary(userId, diaryRequest); return ResponseEntity.ok("일기가 생성되었습니다."); } - @GetMapping("/diaries") - public ResponseEntity> getDiaries( - @RequestParam(name = "category", required = false) Category category, - @RequestParam(name = "sortByContentLength",required = false, defaultValue = "false")final Boolean sortByContentLength) { - - - final List diariesResponses; - // 각 조건에 따라 한번만 할당되고 추가로 변경되지 않음을 명확하게 하기 위해 final 사용 - - if (category != null) { - // 카테고리로 정렬 - diariesResponses = diaryService.getDiaryListSortByCategory(category); - } else if (sortByContentLength) { - - // 글자수로 정렬 - diariesResponses = diaryService.getDiaryListSortByContent(); - } else { - //최신순으로 정렬 - diariesResponses = diaryService.getDiaryList(); - } - - return ResponseEntity.ok(diariesResponses); - } @GetMapping("/diary/{id}") ResponseEntity getDiary(@PathVariable(name = "id") final Long id) { diff --git a/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java b/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java index 3ba637c..c89b32d 100644 --- a/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java +++ b/src/main/java/org/sopt/Diary/dto/req/DiaryReq.java @@ -1,9 +1,12 @@ package org.sopt.Diary.dto.req; +import jakarta.validation.constraints.NotNull; import org.sopt.Diary.entity.Category; -public record DiaryReq(String title, - String content, - Category category){ + +public record DiaryReq(@NotNull String title, + @NotNull String content, + @NotNull Category category, + boolean isPrivate){ } diff --git a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java index 0c4045c..2a1c715 100644 --- a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -32,11 +32,11 @@ public class DiaryEntity { //JPA 는 엔티티 객체를 생성할때 기본 생성자를 사용하므로 반드시 있어야 한다! public DiaryEntity() {} - public DiaryEntity(String title, String content,Category category) { + public DiaryEntity(final String title,final String content,final Category category,final Boolean isPrivate) { this.title = title; this.content = content; this.category = category; - + this.isPrivate =isPrivate; } diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index e177154..794f4b8 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -22,18 +22,19 @@ public class DiaryService { private final static int LIMIT_MINUTE = 5; private final static int LIMIT_DIARY = 10; private final DiaryRepository diaryRepository; + private final UserService userService; - public DiaryService(DiaryRepository diaryRepository) { + public DiaryService(DiaryRepository diaryRepository, UserService userService) { this.diaryRepository = diaryRepository; + this.userService = userService; } - public void validateTitle(String title){ - if(diaryRepository.existsByTitle(title)){ - throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"중복왼 제목은 북자능 합니다."); - } - } + final public void createDiary(final long userId, final DiaryReq diaryRequest) { + + if(!userService.findById(userId)){ + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } - public void createDiary(DiaryReq diaryRequest) { validateTitle(diaryRequest.title()); int minutesSinceLastDiary = calculateMinutesSinceLastDiary(); @@ -41,21 +42,14 @@ public void createDiary(DiaryReq diaryRequest) { throw new ResponseStatusException(HttpStatus.TOO_MANY_REQUESTS, "5분 뒤에 요청해주세요"); } - Diary diary = new Diary(diaryRequest.title(), diaryRequest.content(), diaryRequest.category()); - diaryRepository.save(new DiaryEntity(diary.getTitle(), diary.getContent(), diary.getCategory())); + diaryRepository.save( + new DiaryEntity(diaryRequest.title(), + diaryRequest.content(), + diaryRequest.category(), + diaryRequest.isPrivate()) + ); } - private int calculateMinutesSinceLastDiary() { - DiaryEntity latestDiary = diaryRepository.findTop1ByOrderByCreatedAtDesc(); - - if (latestDiary != null) { - LocalDateTime now = LocalDateTime.now(); - LocalDateTime latest = latestDiary.getCreatedAt(); - Duration duration = Duration.between(latest, now); - return duration.toMinutesPart(); - } - return Integer.MAX_VALUE; // 다이어리가 없을 경우, 제한 시간이 없도록 큰 값 반환 - } private List toDiariesResponse(List diaryEntities) { List diariesResponses = new ArrayList<>(); @@ -107,4 +101,23 @@ public DiaryEntity findById(Long id){ return diaryRepository.findById(id) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); } + + + public void validateTitle(String title){ + if(diaryRepository.existsByTitle(title)){ + throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"중복된 제목은 불가능 합니다."); + } + } + + private int calculateMinutesSinceLastDiary() { + DiaryEntity latestDiary = diaryRepository.findTop1ByOrderByCreatedAtDesc(); + + if (latestDiary != null) { + LocalDateTime now = LocalDateTime.now(); + LocalDateTime latest = latestDiary.getCreatedAt(); + Duration duration = Duration.between(latest, now); + return duration.toMinutesPart(); + } + return Integer.MAX_VALUE; // 다이어리가 없을 경우, 제한 시간이 없도록 큰 값 반환 + } } \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/service/UserService.java b/src/main/java/org/sopt/Diary/service/UserService.java index 9af3a3f..b6677ce 100644 --- a/src/main/java/org/sopt/Diary/service/UserService.java +++ b/src/main/java/org/sopt/Diary/service/UserService.java @@ -43,4 +43,9 @@ public Long login(@Valid final SignInReq signInReq) { // 2. UserID 반환 return findUser.getId(); } + + public boolean findById(@Valid final long userId){ + Optional findUser = userRepository.findById(userId); + return findUser.isPresent(); + } } From 28dde74df4fb7570c1ba912ea86cec4bccbf273d Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 11:45:41 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat(diary)=20:=20=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=A6=AC=20=EA=B0=9C=EB=B3=84=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +++ .../sopt/Diary/Formatter/DiaryFormatter.java | 4 +++ .../Diary/controller/DiaryController.java | 30 ++++++++++--------- .../Diary/repository/DiaryRepository.java | 5 ++++ .../sopt/Diary/service/DiariesService.java | 6 ++++ .../org/sopt/Diary/service/DiaryService.java | 26 +++++++++------- .../sopt/Diary/validator/DiaryValidator.java | 16 ++++++++++ 7 files changed, 66 insertions(+), 25 deletions(-) create mode 100644 src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java create mode 100644 src/main/java/org/sopt/Diary/service/DiariesService.java create mode 100644 src/main/java/org/sopt/Diary/validator/DiaryValidator.java diff --git a/build.gradle b/build.gradle index 457689a..8fa02bc 100644 --- a/build.gradle +++ b/build.gradle @@ -34,4 +34,8 @@ dependencies { test { useJUnitPlatform() +} + +tasks.withType(JavaCompile) { + options.compilerArgs << "-parameters" } \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java b/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java new file mode 100644 index 0000000..fa80255 --- /dev/null +++ b/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java @@ -0,0 +1,4 @@ +package org.sopt.Diary.Formatter; + +public class DiaryFormatter { +} diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index 54596c4..18b2840 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -26,8 +26,14 @@ public DiaryController(DiaryService diaryService) { private final static int LENGTH_LIMIT = 30; + /** + * 일기 작성하기 + * @param userId 유저 Id(Header) + * @param diaryRequest title,content,category,isPrivate + * @return 200 + */ @PostMapping() - ResponseEntity postDiary(@RequestHeader("userId") Long userId, @Valid @RequestBody final DiaryReq diaryRequest) { + ResponseEntity postDiary(@RequestHeader("userId") long userId, @Valid @RequestBody final DiaryReq diaryRequest) { if(diaryRequest.content().length()>LENGTH_LIMIT){ return ResponseEntity.badRequest().body("글자 수는 30자를 넘을 수 없습니다"); @@ -38,22 +44,18 @@ ResponseEntity postDiary(@RequestHeader("userId") Long userId, @Valid @R } - @GetMapping("/diary/{id}") - ResponseEntity getDiary(@PathVariable(name = "id") final Long id) { - final Diary savedDiary = diaryService.getDiary(id); - - // new 가 아닌 factory 메소드를 사용하면 불변 객체를 만들 수 있는데... 이 부분에 대해서 고민중.. - final DiaryResponse diaryResponse = new DiaryResponse( - savedDiary.getId(), - savedDiary.getTitle(), - savedDiary.getContent(), - savedDiary.getCreatedAt(), - savedDiary.getCategory() - ); - + /** + * 일기 상세 조회 + * @param diaryId 다이어리 아이디 + * @return 200 + */ + @GetMapping("/{diaryId}") + ResponseEntity getDiary( @PathVariable("diaryId") final long diaryId) { + final DiaryResponse diaryResponse = diaryService.getDiary(diaryId); return ResponseEntity.ok(diaryResponse); } + @PatchMapping("/diary/{id}") ResponseEntity updateDiary(@PathVariable(name = "id") final Long id, @RequestBody DiaryUpdateReq diaryRequest){ diff --git a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java index 16b582a..4c4ceff 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java +++ b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java @@ -4,9 +4,11 @@ import org.sopt.Diary.entity.DiaryEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Optional; @Component public interface DiaryRepository extends JpaRepository { @@ -22,4 +24,7 @@ public interface DiaryRepository extends JpaRepository { List findByContentLength(); List findByCategory(Category category); + + Optional findByIdAndIsPrivateFalse(Long id); + } diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java new file mode 100644 index 0000000..2a737e3 --- /dev/null +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -0,0 +1,6 @@ +package org.sopt.Diary.service; + +public class DiariesService { + +} + diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index 794f4b8..7b68911 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -1,18 +1,18 @@ package org.sopt.Diary.service; -import org.sopt.Diary.dto.Diary; import org.sopt.Diary.dto.res.DiariesResponse; import org.sopt.Diary.dto.req.DiaryReq; +import org.sopt.Diary.dto.res.DiaryResponse; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.server.ResponseStatusException; import java.time.Duration; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -50,6 +50,15 @@ final public void createDiary(final long userId, final DiaryReq diaryRequest) { ); } + public DiaryResponse getDiary(long id) { + DiaryEntity diaryEntity = findById(id); + return new DiaryResponse(diaryEntity.getId(), + diaryEntity.getTitle(), + diaryEntity.getContent(), + diaryEntity.getContent(), + diaryEntity.getCategory()); + } + private List toDiariesResponse(List diaryEntities) { List diariesResponses = new ArrayList<>(); @@ -79,13 +88,7 @@ public List getDiaryListSortByCategory(Category category) { return toDiariesResponse(diaryEntities); } - public Diary getDiary(Long id) { - DiaryEntity diaryEntity = findById(id); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - String formattedDate = diaryEntity.getCreatedAt().format(formatter); - return new Diary(diaryEntity.getId(), diaryEntity.getTitle(), diaryEntity.getContent(), formattedDate, diaryEntity.getCategory()); - } public void patchDiary(Long id, String content, Category category) { DiaryEntity diaryEntity= findById(id); @@ -97,12 +100,13 @@ public void deleteDiary(Long id) { diaryRepository.delete(diaryEntity); } - public DiaryEntity findById(Long id){ - return diaryRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + public DiaryEntity findById(final long id){ + return diaryRepository.findByIdAndIsPrivateFalse(id) + .orElseThrow(() -> new HttpServerErrorException(HttpStatus.NOT_FOUND)); } + public void validateTitle(String title){ if(diaryRepository.existsByTitle(title)){ throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"중복된 제목은 불가능 합니다."); diff --git a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java new file mode 100644 index 0000000..c2764e3 --- /dev/null +++ b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java @@ -0,0 +1,16 @@ +package org.sopt.Diary.validator; + +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Component +public class DiaryValidator { + + public static String dateFormatter(LocalDateTime createdDate){ + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); //ForMat 을 하는 부분이 + return createdDate.format(formatter); + + } +} From fa17ddab0a7b0acb665d64cf357f4b4acc6a4817 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 12:22:36 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat(diaty)=20:=20=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=A6=AC=20=EC=88=98=EC=A0=95=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/Diary/Formatter/DiaryFormatter.java | 10 +++++ .../Diary/controller/DiaryController.java | 30 ++++++++------- .../org/sopt/Diary/entity/DiaryEntity.java | 15 ++++++-- .../org/sopt/Diary/service/DiaryService.java | 38 +++++++++++-------- .../org/sopt/Diary/service/UserService.java | 8 ++-- .../sopt/Diary/validator/DiaryValidator.java | 11 +++--- 6 files changed, 71 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java b/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java index fa80255..099b052 100644 --- a/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java +++ b/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java @@ -1,4 +1,14 @@ package org.sopt.Diary.Formatter; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Component public class DiaryFormatter { + public static String dateFormatter(LocalDateTime createdDate){ + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); //ForMat 을 하는 부분이 + return createdDate.format(formatter); + } } diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index 18b2840..04ad938 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -8,6 +8,8 @@ import org.sopt.Diary.entity.Category; import org.sopt.Diary.dto.Diary; import org.sopt.Diary.service.DiaryService; +import org.sopt.Diary.service.UserService; +import org.sopt.Diary.validator.DiaryValidator; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -19,13 +21,12 @@ public class DiaryController { private final DiaryService diaryService; - - public DiaryController(DiaryService diaryService) { + private final UserService userService; + public DiaryController(DiaryService diaryService,UserService userService) { this.diaryService = diaryService; + this.userService=userService; } - private final static int LENGTH_LIMIT = 30; - /** * 일기 작성하기 * @param userId 유저 Id(Header) @@ -35,15 +36,14 @@ public DiaryController(DiaryService diaryService) { @PostMapping() ResponseEntity postDiary(@RequestHeader("userId") long userId, @Valid @RequestBody final DiaryReq diaryRequest) { - if(diaryRequest.content().length()>LENGTH_LIMIT){ - return ResponseEntity.badRequest().body("글자 수는 30자를 넘을 수 없습니다"); - } + //UserId, 내용 글자수 검증 + userService.findByUserId(userId); + DiaryValidator.checkContent(diaryRequest.content()); diaryService.createDiary(userId, diaryRequest); return ResponseEntity.ok("일기가 생성되었습니다."); } - /** * 일기 상세 조회 * @param diaryId 다이어리 아이디 @@ -55,14 +55,16 @@ ResponseEntity getDiary( @PathVariable("diaryId") final long diar return ResponseEntity.ok(diaryResponse); } + @PatchMapping("/{diaryId}") + ResponseEntity updateDiary(@RequestHeader("userId") long userId, + @PathVariable("diaryId") final long diaryId, + @Valid @RequestBody DiaryUpdateReq diaryRequest){ - @PatchMapping("/diary/{id}") - ResponseEntity updateDiary(@PathVariable(name = "id") final Long id, @RequestBody DiaryUpdateReq diaryRequest){ + //UserId, 내용 글자수 검증 + userService.findByUserId(userId); + DiaryValidator.checkContent(diaryRequest.content()); - if (diaryRequest.content().length() > LENGTH_LIMIT) { - return ResponseEntity.badRequest().body("글자 수는 30자를 넘을 수 없습니다"); - } - diaryService.patchDiary(id,diaryRequest.content(),diaryRequest.category()); + diaryService.patchDiary(userId, diaryId,diaryRequest.content(),diaryRequest.category()); return ResponseEntity.ok("일기가 수정되었습니다."); } diff --git a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java index 2a1c715..90b462a 100644 --- a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -9,6 +9,7 @@ public class DiaryEntity { @Id + @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -29,26 +30,31 @@ public class DiaryEntity { @Enumerated(EnumType.STRING) //enum 이름 그대로 DB에 저장된다 private Category category; + @Column(name="user_id") + private Long userId; + //JPA 는 엔티티 객체를 생성할때 기본 생성자를 사용하므로 반드시 있어야 한다! public DiaryEntity() {} - public DiaryEntity(final String title,final String content,final Category category,final Boolean isPrivate) { + public DiaryEntity(final String title,final String content,final Category category,final boolean isPrivate,final long userId) { this.title = title; this.content = content; this.category = category; this.isPrivate =isPrivate; + this.userId = userId; } - public DiaryEntity(final Long id, final String title, final String content, final LocalDateTime createdAt, final Category category) { + public DiaryEntity(final long id, final String title, final String content, final LocalDateTime createdAt, final Category category,final long userId) { this. id = id; this.title = title; this.content = content; this.createdAt = createdAt; this.category = category; + this.userId= userId; } - public long getId(){ + public long getDiaryId(){ return id; } @@ -66,6 +72,9 @@ public LocalDateTime getCreatedAt() { public Category getCategory(){ return category; } + public long getUserId(){ + return userId; + } } diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index 7b68911..d457929 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -31,10 +31,7 @@ public DiaryService(DiaryRepository diaryRepository, UserService userService) { final public void createDiary(final long userId, final DiaryReq diaryRequest) { - if(!userService.findById(userId)){ - throw new ResponseStatusException(HttpStatus.NOT_FOUND); - } - + findByDiaryId(userId); validateTitle(diaryRequest.title()); int minutesSinceLastDiary = calculateMinutesSinceLastDiary(); @@ -46,19 +43,33 @@ final public void createDiary(final long userId, final DiaryReq diaryRequest) { new DiaryEntity(diaryRequest.title(), diaryRequest.content(), diaryRequest.category(), - diaryRequest.isPrivate()) + diaryRequest.isPrivate(), + userId) ); } - public DiaryResponse getDiary(long id) { - DiaryEntity diaryEntity = findById(id); - return new DiaryResponse(diaryEntity.getId(), + public DiaryResponse getDiary(final long id) { + DiaryEntity diaryEntity = findByDiaryId(id); + return new DiaryResponse(diaryEntity.getDiaryId(), diaryEntity.getTitle(), diaryEntity.getContent(), diaryEntity.getContent(), diaryEntity.getCategory()); } + public void patchDiary(final long userId, final long diaryId, final String content, final Category category) { + DiaryEntity diaryEntity= findByDiaryId(diaryId); + if(diaryEntity.getUserId()!=userId){ + throw new ResponseStatusException(HttpStatus.FORBIDDEN); + } + diaryRepository.save(new DiaryEntity(diaryEntity.getDiaryId(), + diaryEntity.getTitle(), + content, + diaryEntity.getCreatedAt(), + category, + diaryEntity.getUserId())); + } + private List toDiariesResponse(List diaryEntities) { List diariesResponses = new ArrayList<>(); @@ -66,7 +77,7 @@ private List toDiariesResponse(List diaryEntities) for (DiaryEntity diary : diaryEntities) { if (count >= LIMIT_DIARY) break; - DiariesResponse diariesResponse = new DiariesResponse(diary.getId(), diary.getTitle()); + DiariesResponse diariesResponse = new DiariesResponse(diary.getDiaryId(), diary.getTitle()); diariesResponses.add(diariesResponse); count++; } @@ -90,17 +101,14 @@ public List getDiaryListSortByCategory(Category category) { - public void patchDiary(Long id, String content, Category category) { - DiaryEntity diaryEntity= findById(id); - diaryRepository.save(new DiaryEntity(diaryEntity.getId(), diaryEntity.getTitle(), content, diaryEntity.getCreatedAt(), category)); - } + public void deleteDiary(Long id) { - DiaryEntity diaryEntity= findById(id); + DiaryEntity diaryEntity= findByDiaryId(id); diaryRepository.delete(diaryEntity); } - public DiaryEntity findById(final long id){ + public DiaryEntity findByDiaryId(final long id){ return diaryRepository.findByIdAndIsPrivateFalse(id) .orElseThrow(() -> new HttpServerErrorException(HttpStatus.NOT_FOUND)); } diff --git a/src/main/java/org/sopt/Diary/service/UserService.java b/src/main/java/org/sopt/Diary/service/UserService.java index b6677ce..dcf7ddb 100644 --- a/src/main/java/org/sopt/Diary/service/UserService.java +++ b/src/main/java/org/sopt/Diary/service/UserService.java @@ -44,8 +44,10 @@ public Long login(@Valid final SignInReq signInReq) { return findUser.getId(); } - public boolean findById(@Valid final long userId){ - Optional findUser = userRepository.findById(userId); - return findUser.isPresent(); + // UserService.java + public UserEntity findByUserId(final long userId) { + return userRepository.findById(userId) + .orElseThrow(() -> new IllegalStateException("존재하지 않는 사용자입니다.")); } + } diff --git a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java index c2764e3..9e647bd 100644 --- a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java +++ b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java @@ -2,15 +2,14 @@ import org.springframework.stereotype.Component; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - @Component public class DiaryValidator { - public static String dateFormatter(LocalDateTime createdDate){ - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); //ForMat 을 하는 부분이 - return createdDate.format(formatter); + private final static int LENGTH_LIMIT = 30; + public static void checkContent(String content) { + if(content.length() > LENGTH_LIMIT){ + throw new IllegalArgumentException("글자 수는 30자를 넘을 수 없습니다"); + } } } From 9c3e9001f1d9e0318841906b585e83a7b9fb06c5 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 14:06:38 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat(diaries)=20:=20=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=A6=AC=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Diary/controller/DiariesController.java | 50 +++++----- .../Diary/controller/DiaryController.java | 15 ++- src/main/java/org/sopt/Diary/dto/Diary.java | 52 ---------- src/main/java/org/sopt/Diary/dto/UserDTO.java | 7 -- .../sopt/Diary/dto/req/DiaryUpdateReq.java | 3 +- .../sopt/Diary/dto/res/DiariesResponse.java | 2 +- .../sopt/Diary/dto/res/DiaryListResponse.java | 18 +++- .../java/org/sopt/Diary/entity/SortType.java | 5 + .../org/sopt/Diary/entity/UserEntity.java | 4 +- .../Diary/repository/DiaryRepository.java | 31 ++++-- .../sopt/Diary/service/DiariesService.java | 99 +++++++++++++++++++ .../org/sopt/Diary/service/DiaryService.java | 87 +++++----------- .../sopt/Diary/validator/DiaryValidator.java | 15 ++- 13 files changed, 214 insertions(+), 174 deletions(-) delete mode 100644 src/main/java/org/sopt/Diary/dto/Diary.java delete mode 100644 src/main/java/org/sopt/Diary/dto/UserDTO.java create mode 100644 src/main/java/org/sopt/Diary/entity/SortType.java diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java index 190ff24..92a9921 100644 --- a/src/main/java/org/sopt/Diary/controller/DiariesController.java +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -1,48 +1,44 @@ package org.sopt.Diary.controller; +import jakarta.validation.Valid; import org.sopt.Diary.dto.res.DiariesResponse; +import org.sopt.Diary.dto.res.DiaryListResponse; import org.sopt.Diary.entity.Category; +import org.sopt.Diary.entity.SortType; +import org.sopt.Diary.service.DiariesService; import org.sopt.Diary.service.DiaryService; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; -@RequestMapping("diaries") +@RequestMapping("/diaries") @RestController public class DiariesController { - private final DiaryService diaryService; + private final DiariesService diariesService; - public DiariesController(DiaryService diaryService) { - this.diaryService = diaryService; + public DiariesController(DiariesService diariesService) { + this.diariesService = diariesService; } - @GetMapping("/diaries") - public ResponseEntity> getDiaries( - @RequestParam(name = "category", required = false) Category category, - @RequestParam(name = "sortByContentLength",required = false, defaultValue = "false")final Boolean sortByContentLength) { + @GetMapping() + public ResponseEntity getDiaries( + @RequestParam(name = "category") final Category category, + @RequestParam(name = "sort",required = false, defaultValue = "latest") final SortType sortType) { + DiaryListResponse diaryListResponse = diariesService.getDiariesResponse(category, sortType, false, 0); + return ResponseEntity.ok(diaryListResponse); + } - final List diariesResponses; - // 각 조건에 따라 한번만 할당되고 추가로 변경되지 않음을 명확하게 하기 위해 final 사용 - - if (category != null) { - // 카테고리로 정렬 - diariesResponses = diaryService.getDiaryListSortByCategory(category); - } else if (sortByContentLength) { - - // 글자수로 정렬 - diariesResponses = diaryService.getDiaryListSortByContent(); - } else { - //최신순으로 정렬 - diariesResponses = diaryService.getDiaryList(); - } + @GetMapping("/my") + public ResponseEntity getMyDiaries( + @RequestHeader("userId") long userId, + @RequestParam(name = "category") final Category category, + @RequestParam(name = "sort",required = false, defaultValue = "latest")final SortType sortType) { - return ResponseEntity.ok(diariesResponses); + DiaryListResponse diaryListResponse = diariesService.getDiariesResponse(category, sortType, true, userId); + return ResponseEntity.ok(diaryListResponse); } } diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index 04ad938..2d0129c 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -2,20 +2,14 @@ import jakarta.validation.Valid; import org.sopt.Diary.dto.req.DiaryUpdateReq; -import org.sopt.Diary.dto.res.DiariesResponse; import org.sopt.Diary.dto.req.DiaryReq; import org.sopt.Diary.dto.res.DiaryResponse; -import org.sopt.Diary.entity.Category; -import org.sopt.Diary.dto.Diary; import org.sopt.Diary.service.DiaryService; import org.sopt.Diary.service.UserService; import org.sopt.Diary.validator.DiaryValidator; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; - -import java.util.List; - @RequestMapping("/diary") @RestController public class DiaryController { @@ -39,6 +33,7 @@ ResponseEntity postDiary(@RequestHeader("userId") long userId, @Valid @R //UserId, 내용 글자수 검증 userService.findByUserId(userId); DiaryValidator.checkContent(diaryRequest.content()); + DiaryValidator.checkTitle(diaryRequest.title()); diaryService.createDiary(userId, diaryRequest); return ResponseEntity.ok("일기가 생성되었습니다."); @@ -68,9 +63,11 @@ ResponseEntity updateDiary(@RequestHeader("userId") long userId, return ResponseEntity.ok("일기가 수정되었습니다."); } - @DeleteMapping("/diary/{id}") - ResponseEntity deleteDiary(@PathVariable(name = "id") final Long id){ - diaryService.deleteDiary(id); + @DeleteMapping("/{diaryId}") + ResponseEntity deleteDiary(@RequestHeader("userId") long userId, + @PathVariable("diaryId") final long diaryId){ + userService.findByUserId(userId); + diaryService.deleteDiary(userId,diaryId); return ResponseEntity.ok("일기가 삭제되었습니다."); } } diff --git a/src/main/java/org/sopt/Diary/dto/Diary.java b/src/main/java/org/sopt/Diary/dto/Diary.java deleted file mode 100644 index 9594c6e..0000000 --- a/src/main/java/org/sopt/Diary/dto/Diary.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.sopt.Diary.dto; - -import org.sopt.Diary.entity.Category; - -public class Diary { - private long id; - private final String title; - private final String content; - private String createdAt; - private Category category; - - public Diary(long id, String title, String content, String date,Category category){ - this.id = id; - this.title = title; - this.content = content; - this.createdAt= date; - this.category = category; - } - - - public Diary(String title, String content,Category category){ - this.title = title; - this.content = content; - this.category = category; - } - - public Diary(long id, String content){ - this.id= id; - this.title = null; - this.content = content; - } - - public long getId(){ - return id; - } - - public String getTitle(){ - return title; - } - - public String getContent() { - return content; - } - - public String getCreatedAt() { - return createdAt; - } - - public Category getCategory(){ - return category; - } -} diff --git a/src/main/java/org/sopt/Diary/dto/UserDTO.java b/src/main/java/org/sopt/Diary/dto/UserDTO.java deleted file mode 100644 index 51adedf..0000000 --- a/src/main/java/org/sopt/Diary/dto/UserDTO.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.sopt.Diary.dto; - -public record UserDTO ( Long id, - String loginId, - String nickname){ - -} diff --git a/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java b/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java index 0a7a0a3..4832412 100644 --- a/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java +++ b/src/main/java/org/sopt/Diary/dto/req/DiaryUpdateReq.java @@ -1,7 +1,8 @@ package org.sopt.Diary.dto.req; +import jakarta.validation.constraints.NotNull; import org.sopt.Diary.entity.Category; -public record DiaryUpdateReq(String content , Category category) { +public record DiaryUpdateReq(@NotNull String content , @NotNull Category category) { } diff --git a/src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java b/src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java index 5ad7cf8..a90b2fb 100644 --- a/src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java +++ b/src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java @@ -1,6 +1,6 @@ package org.sopt.Diary.dto.res; -public record DiariesResponse(Long id, String title){ +public record DiariesResponse(Long id, String username,String title, String cratedAt){ } //레코드를 이용하도록 수정- // - 레코드를 사용하면 모든 필드가 자동으로 final이 되고 diff --git a/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java b/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java index 2669a4f..b1c4f63 100644 --- a/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java +++ b/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java @@ -1,6 +1,20 @@ package org.sopt.Diary.dto.res; + import java.util.List; -public record DiaryListResponse(List diaries) { } -// 레코드 생성자 변경 \ No newline at end of file +public class DiaryListResponse { + private List diaries; + + public DiaryListResponse(List diaries) { + this.diaries = diaries; + } + + public List getDiaries() { + return diaries; + } + + public void setDiaries(List diaries) { + this.diaries = diaries; + } +} \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/entity/SortType.java b/src/main/java/org/sopt/Diary/entity/SortType.java new file mode 100644 index 0000000..13c2efd --- /dev/null +++ b/src/main/java/org/sopt/Diary/entity/SortType.java @@ -0,0 +1,5 @@ +package org.sopt.Diary.entity; + +public enum SortType { + latest,quantity +} diff --git a/src/main/java/org/sopt/Diary/entity/UserEntity.java b/src/main/java/org/sopt/Diary/entity/UserEntity.java index 22140a3..f250e6f 100644 --- a/src/main/java/org/sopt/Diary/entity/UserEntity.java +++ b/src/main/java/org/sopt/Diary/entity/UserEntity.java @@ -1,7 +1,6 @@ package org.sopt.Diary.entity; import jakarta.persistence.*; -import org.sopt.Diary.dto.UserDTO; @Entity @Table(name="user") @@ -36,6 +35,9 @@ public static UserEntity createUser(final String loginId,final String password, public long getId(){ return this.id; } + public String getNickname(){ + return this.nickname; + } diff --git a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java index 4c4ceff..7ab478a 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java +++ b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java @@ -14,17 +14,34 @@ public interface DiaryRepository extends JpaRepository { - List findTop10ByOrderByCreatedAtDesc(); + Boolean existsByTitle(String title); - DiaryEntity findTop1ByOrderByCreatedAtDesc(); + Optional findByIdAndIsPrivateFalse(Long id); - Boolean existsByTitle(String title); + //카테고리 필터링 + Optional> findByCategoryAndIsPrivateFalseOrderByCreatedAtDesc(Category category); - @Query("SELECT d FROM DiaryEntity d ORDER BY LENGTH(d.content) DESC") - List findByContentLength(); + @Query("SELECT d FROM DiaryEntity d WHERE d.category = :category AND d.isPrivate = false ORDER BY LENGTH(d.content) DESC") + Optional> findByCategoryAndIsPrivateFalseOrderByContentLengthDesc(@Param("category") Category category); - List findByCategory(Category category); - Optional findByIdAndIsPrivateFalse(Long id); + //카테고리 필터링 - MyDiary + Optional> findByUserIdAndCategoryOrderByCreatedAtDesc(long userId, Category category); + + @Query("SELECT d FROM DiaryEntity d WHERE d.category = :category AND d.userId = :userId ORDER BY LENGTH(d.content) DESC") + Optional> findByUserIdAndCategoryOrderByContentLengthDesc(@Param("userId") long userId, @Param("category") Category category); + + + //카테고리 필터링 X - 전체 조회 + Optional> findAllByIsPrivateFalseOrderByCreatedAtDesc(); + + @Query("SELECT d FROM DiaryEntity d WHERE d.isPrivate = false ORDER BY LENGTH(d.content) DESC") + Optional> findAllByIsPrivateFalseOrderByContentLengthDesc(); + + + //카테고리 필터링 X - MyDiary + @Query("SELECT d FROM DiaryEntity d WHERE d.userId = :userId ORDER BY LENGTH(d.content) DESC") + Optional> findByUserIdOrderByContentLengthDesc(@Param("userId") long userId); + Optional> findByUserIdOrderByCreatedAtDesc(@Param("userId") long userId); } diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index 2a737e3..7315c46 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -1,6 +1,105 @@ package org.sopt.Diary.service; +import org.sopt.Diary.Formatter.DiaryFormatter; +import org.sopt.Diary.dto.res.DiariesResponse; +import org.sopt.Diary.dto.res.DiaryListResponse; +import org.sopt.Diary.entity.Category; +import org.sopt.Diary.entity.DiaryEntity; +import org.sopt.Diary.entity.SortType; +import org.sopt.Diary.entity.UserEntity; +import org.sopt.Diary.repository.DiaryRepository; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ResponseStatusException; + +import java.util.ArrayList; +import java.util.List; + +@Component public class DiariesService { + private final static int LIMIT_DIARY = 10; + private final DiaryRepository diaryRepository; + private final UserService userService; + + public DiariesService(DiaryRepository diaryRepository, UserService userService) { + this.diaryRepository = diaryRepository; + this.userService = userService; + } + + private List getDiaryResponse(List diaryEntities) { + List diariesResponses = new ArrayList<>(); + int count =0; + for (DiaryEntity diary : diaryEntities) { + if(count < LIMIT_DIARY) { + final UserEntity user = userService.findByUserId(diary.getUserId()); + final String createdAt = DiaryFormatter.dateFormatter(diary.getCreatedAt()); + DiariesResponse diariesResponse = new DiariesResponse(diary.getDiaryId(), user.getNickname(), diary.getTitle(), createdAt); + diariesResponses.add(diariesResponse); + count++; + } + } + return diariesResponses; + } + + public List getDiaryList(Category category, SortType sortType) { + List diaryEntities; + + if (category == Category.all) { + diaryEntities = switch (sortType) { + case latest -> diaryRepository.findAllByIsPrivateFalseOrderByCreatedAtDesc() + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + case quantity -> diaryRepository.findAllByIsPrivateFalseOrderByContentLengthDesc() + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + }; + } else { + diaryEntities = switch (sortType) { + case latest -> diaryRepository.findByCategoryAndIsPrivateFalseOrderByCreatedAtDesc(category) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + case quantity -> diaryRepository.findByCategoryAndIsPrivateFalseOrderByContentLengthDesc(category) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + }; + } + return getDiaryResponse(diaryEntities); + } + + public List getMyDiaryList(long userId, Category category, SortType sortType) { + List diaryEntities; + + if (category == Category.all) { + diaryEntities = switch (sortType) { + case latest -> diaryRepository.findByUserIdOrderByCreatedAtDesc(userId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + case quantity -> diaryRepository.findByUserIdOrderByContentLengthDesc(userId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + + }; + } else { + diaryEntities = switch (sortType) { + case latest -> diaryRepository.findByUserIdAndCategoryOrderByCreatedAtDesc(userId, category) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + case quantity -> diaryRepository.findByUserIdAndCategoryOrderByContentLengthDesc(userId, category) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + }; + } + + return getDiaryResponse(diaryEntities); + } + + public DiaryListResponse getDiariesResponse(Category category, SortType sortType, boolean isMine, long userId) { + List diaryResponses; + + if (isMine) { + diaryResponses = getMyDiaryList(userId, category, sortType); + } else { + diaryResponses = getDiaryList(category, sortType); + } + + return new DiaryListResponse(diaryResponses); + } + + + + } diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index d457929..5a446ae 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -1,6 +1,5 @@ package org.sopt.Diary.service; -import org.sopt.Diary.dto.res.DiariesResponse; import org.sopt.Diary.dto.req.DiaryReq; import org.sopt.Diary.dto.res.DiaryResponse; import org.sopt.Diary.entity.Category; @@ -8,37 +7,29 @@ import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import org.springframework.web.client.HttpServerErrorException; + import org.springframework.web.server.ResponseStatusException; import java.time.Duration; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; + @Component public class DiaryService { private final static int LIMIT_MINUTE = 5; - private final static int LIMIT_DIARY = 10; + private final DiaryRepository diaryRepository; - private final UserService userService; - public DiaryService(DiaryRepository diaryRepository, UserService userService) { + + public DiaryService(DiaryRepository diaryRepository) { this.diaryRepository = diaryRepository; - this.userService = userService; + } final public void createDiary(final long userId, final DiaryReq diaryRequest) { - findByDiaryId(userId); validateTitle(diaryRequest.title()); - - int minutesSinceLastDiary = calculateMinutesSinceLastDiary(); - if (minutesSinceLastDiary < LIMIT_MINUTE) { - throw new ResponseStatusException(HttpStatus.TOO_MANY_REQUESTS, "5분 뒤에 요청해주세요"); - } - diaryRepository.save( new DiaryEntity(diaryRequest.title(), diaryRequest.content(), @@ -49,7 +40,9 @@ final public void createDiary(final long userId, final DiaryReq diaryRequest) { } public DiaryResponse getDiary(final long id) { - DiaryEntity diaryEntity = findByDiaryId(id); + + DiaryEntity diaryEntity = findByDiaryIdPrivateFalse(id); + return new DiaryResponse(diaryEntity.getDiaryId(), diaryEntity.getTitle(), diaryEntity.getContent(), @@ -58,7 +51,9 @@ public DiaryResponse getDiary(final long id) { } public void patchDiary(final long userId, final long diaryId, final String content, final Category category) { - DiaryEntity diaryEntity= findByDiaryId(diaryId); + + DiaryEntity diaryEntity = findByDiaryId(diaryId); + if(diaryEntity.getUserId()!=userId){ throw new ResponseStatusException(HttpStatus.FORBIDDEN); } @@ -70,66 +65,30 @@ public void patchDiary(final long userId, final long diaryId, final String conte diaryEntity.getUserId())); } + public void deleteDiary(final long userId, final long diaryId) { - private List toDiariesResponse(List diaryEntities) { - List diariesResponses = new ArrayList<>(); - int count = 0; + DiaryEntity diaryEntity= findByDiaryId(diaryId); - for (DiaryEntity diary : diaryEntities) { - if (count >= LIMIT_DIARY) break; - DiariesResponse diariesResponse = new DiariesResponse(diary.getDiaryId(), diary.getTitle()); - diariesResponses.add(diariesResponse); - count++; + if(diaryEntity.getUserId()!=userId){ + throw new ResponseStatusException(HttpStatus.FORBIDDEN); } - return diariesResponses; - } - - public List getDiaryList() { - List diaryEntities = diaryRepository.findTop10ByOrderByCreatedAtDesc(); - return toDiariesResponse(diaryEntities); - } - - public List getDiaryListSortByContent() { - List diaryEntities = diaryRepository.findByContentLength(); - return toDiariesResponse(diaryEntities); - } - - public List getDiaryListSortByCategory(Category category) { - List diaryEntities = diaryRepository.findByCategory(category); - return toDiariesResponse(diaryEntities); - } - - - - - - public void deleteDiary(Long id) { - DiaryEntity diaryEntity= findByDiaryId(id); diaryRepository.delete(diaryEntity); } public DiaryEntity findByDiaryId(final long id){ - return diaryRepository.findByIdAndIsPrivateFalse(id) - .orElseThrow(() -> new HttpServerErrorException(HttpStatus.NOT_FOUND)); + return diaryRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,"일기를 찾을 수 없습니다")); } + public DiaryEntity findByDiaryIdPrivateFalse(final long id){ + return diaryRepository.findByIdAndIsPrivateFalse(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,"일기를 찾을 수 없습니다")); + } - - public void validateTitle(String title){ + public void validateTitle(final String title){ if(diaryRepository.existsByTitle(title)){ throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"중복된 제목은 불가능 합니다."); } } - private int calculateMinutesSinceLastDiary() { - DiaryEntity latestDiary = diaryRepository.findTop1ByOrderByCreatedAtDesc(); - - if (latestDiary != null) { - LocalDateTime now = LocalDateTime.now(); - LocalDateTime latest = latestDiary.getCreatedAt(); - Duration duration = Duration.between(latest, now); - return duration.toMinutesPart(); - } - return Integer.MAX_VALUE; // 다이어리가 없을 경우, 제한 시간이 없도록 큰 값 반환 - } } \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java index 9e647bd..d782659 100644 --- a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java +++ b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java @@ -1,15 +1,24 @@ package org.sopt.Diary.validator; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; +import org.springframework.web.server.ResponseStatusException; @Component public class DiaryValidator { - private final static int LENGTH_LIMIT = 30; + private final static int CONTENT_LIMIT = 30; + private final static int TITLE_LIMIT = 10; public static void checkContent(String content) { - if(content.length() > LENGTH_LIMIT){ - throw new IllegalArgumentException("글자 수는 30자를 넘을 수 없습니다"); + if(content.length() > CONTENT_LIMIT || content.isEmpty()){ + throw new ResponseStatusException(HttpStatus.LENGTH_REQUIRED, "내용 글자 수는 1~30자가 되어야 합니다"); + } + } + + public static void checkTitle(String title) { + if(title.length() > TITLE_LIMIT || title.isEmpty()){ + throw new ResponseStatusException(HttpStatus.LENGTH_REQUIRED, "제목 글자 수는 1~10자가 되어야 합니다"); } } } From d31db13aa17758b5e9656c7fa7863ba8697f0d8c Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 14:09:08 +0900 Subject: [PATCH 07/16] =?UTF-8?q?fix:=ED=8C=8C=EC=9D=BC=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Diary/controller/DiariesController.java | 19 +++++-------- .../Diary/controller/DiaryController.java | 8 +++--- .../sopt/Diary/controller/UserController.java | 6 ++--- .../{DiariesResponse.java => DiariesRes.java} | 2 +- .../org/sopt/Diary/dto/res/DiaryListRes.java | 20 ++++++++++++++ .../sopt/Diary/dto/res/DiaryListResponse.java | 20 -------------- .../java/org/sopt/Diary/dto/res/DiaryRes.java | 6 +++++ .../org/sopt/Diary/dto/res/DiaryResponse.java | 6 ----- .../res/{UserResponse.java => UserRes.java} | 4 +-- .../sopt/Diary/repository/UserRepository.java | 1 - .../sopt/Diary/service/DiariesService.java | 27 +++++++++---------- .../org/sopt/Diary/service/DiaryService.java | 11 +++----- 12 files changed, 58 insertions(+), 72 deletions(-) rename src/main/java/org/sopt/Diary/dto/res/{DiariesResponse.java => DiariesRes.java} (77%) create mode 100644 src/main/java/org/sopt/Diary/dto/res/DiaryListRes.java delete mode 100644 src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java create mode 100644 src/main/java/org/sopt/Diary/dto/res/DiaryRes.java delete mode 100644 src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java rename src/main/java/org/sopt/Diary/dto/res/{UserResponse.java => UserRes.java} (70%) diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java index 92a9921..f62b05a 100644 --- a/src/main/java/org/sopt/Diary/controller/DiariesController.java +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -1,17 +1,12 @@ package org.sopt.Diary.controller; -import jakarta.validation.Valid; -import org.sopt.Diary.dto.res.DiariesResponse; -import org.sopt.Diary.dto.res.DiaryListResponse; +import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.SortType; import org.sopt.Diary.service.DiariesService; -import org.sopt.Diary.service.DiaryService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.util.List; - @RequestMapping("/diaries") @RestController public class DiariesController { @@ -24,21 +19,21 @@ public DiariesController(DiariesService diariesService) { @GetMapping() - public ResponseEntity getDiaries( + public ResponseEntity getDiaries( @RequestParam(name = "category") final Category category, @RequestParam(name = "sort",required = false, defaultValue = "latest") final SortType sortType) { - DiaryListResponse diaryListResponse = diariesService.getDiariesResponse(category, sortType, false, 0); - return ResponseEntity.ok(diaryListResponse); + DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType, false, 0); + return ResponseEntity.ok(diaryListRes); } @GetMapping("/my") - public ResponseEntity getMyDiaries( + public ResponseEntity getMyDiaries( @RequestHeader("userId") long userId, @RequestParam(name = "category") final Category category, @RequestParam(name = "sort",required = false, defaultValue = "latest")final SortType sortType) { - DiaryListResponse diaryListResponse = diariesService.getDiariesResponse(category, sortType, true, userId); - return ResponseEntity.ok(diaryListResponse); + DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType, true, userId); + return ResponseEntity.ok(diaryListRes); } } diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index 2d0129c..a39493f 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -3,7 +3,7 @@ import jakarta.validation.Valid; import org.sopt.Diary.dto.req.DiaryUpdateReq; import org.sopt.Diary.dto.req.DiaryReq; -import org.sopt.Diary.dto.res.DiaryResponse; +import org.sopt.Diary.dto.res.DiaryRes; import org.sopt.Diary.service.DiaryService; import org.sopt.Diary.service.UserService; import org.sopt.Diary.validator.DiaryValidator; @@ -45,9 +45,9 @@ ResponseEntity postDiary(@RequestHeader("userId") long userId, @Valid @R * @return 200 */ @GetMapping("/{diaryId}") - ResponseEntity getDiary( @PathVariable("diaryId") final long diaryId) { - final DiaryResponse diaryResponse = diaryService.getDiary(diaryId); - return ResponseEntity.ok(diaryResponse); + ResponseEntity getDiary(@PathVariable("diaryId") final long diaryId) { + final DiaryRes diaryRes = diaryService.getDiary(diaryId); + return ResponseEntity.ok(diaryRes); } @PatchMapping("/{diaryId}") diff --git a/src/main/java/org/sopt/Diary/controller/UserController.java b/src/main/java/org/sopt/Diary/controller/UserController.java index a0d1cea..b4626b1 100644 --- a/src/main/java/org/sopt/Diary/controller/UserController.java +++ b/src/main/java/org/sopt/Diary/controller/UserController.java @@ -3,7 +3,7 @@ import jakarta.validation.Valid; import org.sopt.Diary.dto.req.SignInReq; import org.sopt.Diary.dto.req.SignUpReq; -import org.sopt.Diary.dto.res.UserResponse; +import org.sopt.Diary.dto.res.UserRes; import org.sopt.Diary.service.UserService; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -26,9 +26,9 @@ private void signUp(@Valid @RequestBody SignUpReq signUpRequest){ } @PostMapping("/signin") - private UserResponse signIn(@Valid @RequestBody SignInReq signInReq){ + private UserRes signIn(@Valid @RequestBody SignInReq signInReq){ Long userId= userService.login(signInReq); - return new UserResponse(userId); + return new UserRes(userId); } diff --git a/src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java b/src/main/java/org/sopt/Diary/dto/res/DiariesRes.java similarity index 77% rename from src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java rename to src/main/java/org/sopt/Diary/dto/res/DiariesRes.java index a90b2fb..2b5e56f 100644 --- a/src/main/java/org/sopt/Diary/dto/res/DiariesResponse.java +++ b/src/main/java/org/sopt/Diary/dto/res/DiariesRes.java @@ -1,6 +1,6 @@ package org.sopt.Diary.dto.res; -public record DiariesResponse(Long id, String username,String title, String cratedAt){ +public record DiariesRes(Long id, String username, String title, String cratedAt){ } //레코드를 이용하도록 수정- // - 레코드를 사용하면 모든 필드가 자동으로 final이 되고 diff --git a/src/main/java/org/sopt/Diary/dto/res/DiaryListRes.java b/src/main/java/org/sopt/Diary/dto/res/DiaryListRes.java new file mode 100644 index 0000000..5b20f85 --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/res/DiaryListRes.java @@ -0,0 +1,20 @@ +package org.sopt.Diary.dto.res; + + +import java.util.List; + +public class DiaryListRes { + private List diaries; + + public DiaryListRes(List diaries) { + this.diaries = diaries; + } + + public List getDiaries() { + return diaries; + } + + public void setDiaries(List diaries) { + this.diaries = diaries; + } +} \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java b/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java deleted file mode 100644 index b1c4f63..0000000 --- a/src/main/java/org/sopt/Diary/dto/res/DiaryListResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.sopt.Diary.dto.res; - - -import java.util.List; - -public class DiaryListResponse { - private List diaries; - - public DiaryListResponse(List diaries) { - this.diaries = diaries; - } - - public List getDiaries() { - return diaries; - } - - public void setDiaries(List diaries) { - this.diaries = diaries; - } -} \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/dto/res/DiaryRes.java b/src/main/java/org/sopt/Diary/dto/res/DiaryRes.java new file mode 100644 index 0000000..ec6bcc0 --- /dev/null +++ b/src/main/java/org/sopt/Diary/dto/res/DiaryRes.java @@ -0,0 +1,6 @@ +package org.sopt.Diary.dto.res; + +import org.sopt.Diary.entity.Category; + +public record DiaryRes(long id, String title, String content, String createdAt, Category category) { +} \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java b/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java deleted file mode 100644 index 76773af..0000000 --- a/src/main/java/org/sopt/Diary/dto/res/DiaryResponse.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.sopt.Diary.dto.res; - -import org.sopt.Diary.entity.Category; - -public record DiaryResponse(long id, String title, String content, String createdAt, Category category) { -} \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/dto/res/UserResponse.java b/src/main/java/org/sopt/Diary/dto/res/UserRes.java similarity index 70% rename from src/main/java/org/sopt/Diary/dto/res/UserResponse.java rename to src/main/java/org/sopt/Diary/dto/res/UserRes.java index bc20b35..df6b034 100644 --- a/src/main/java/org/sopt/Diary/dto/res/UserResponse.java +++ b/src/main/java/org/sopt/Diary/dto/res/UserRes.java @@ -1,10 +1,10 @@ package org.sopt.Diary.dto.res; -public class UserResponse { +public class UserRes { private long userId; - public UserResponse(long userId){ + public UserRes(long userId){ this.userId = userId; } diff --git a/src/main/java/org/sopt/Diary/repository/UserRepository.java b/src/main/java/org/sopt/Diary/repository/UserRepository.java index a3a9cef..d5750ab 100644 --- a/src/main/java/org/sopt/Diary/repository/UserRepository.java +++ b/src/main/java/org/sopt/Diary/repository/UserRepository.java @@ -3,7 +3,6 @@ import org.sopt.Diary.entity.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; import java.util.Optional; public interface UserRepository extends JpaRepository { diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index 7315c46..270f7aa 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -1,8 +1,8 @@ package org.sopt.Diary.service; import org.sopt.Diary.Formatter.DiaryFormatter; -import org.sopt.Diary.dto.res.DiariesResponse; -import org.sopt.Diary.dto.res.DiaryListResponse; +import org.sopt.Diary.dto.res.DiariesRes; +import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.entity.SortType; @@ -27,22 +27,22 @@ public DiariesService(DiaryRepository diaryRepository, UserService userService) this.userService = userService; } - private List getDiaryResponse(List diaryEntities) { - List diariesResponses = new ArrayList<>(); + private List getDiaryResponse(List diaryEntities) { + List diariesRespons = new ArrayList<>(); int count =0; for (DiaryEntity diary : diaryEntities) { if(count < LIMIT_DIARY) { final UserEntity user = userService.findByUserId(diary.getUserId()); final String createdAt = DiaryFormatter.dateFormatter(diary.getCreatedAt()); - DiariesResponse diariesResponse = new DiariesResponse(diary.getDiaryId(), user.getNickname(), diary.getTitle(), createdAt); - diariesResponses.add(diariesResponse); + DiariesRes diariesRes = new DiariesRes(diary.getDiaryId(), user.getNickname(), diary.getTitle(), createdAt); + diariesRespons.add(diariesRes); count++; } } - return diariesResponses; + return diariesRespons; } - public List getDiaryList(Category category, SortType sortType) { + public List getDiaryList(Category category, SortType sortType) { List diaryEntities; if (category == Category.all) { @@ -63,7 +63,7 @@ public List getDiaryList(Category category, SortType sortType) return getDiaryResponse(diaryEntities); } - public List getMyDiaryList(long userId, Category category, SortType sortType) { + public List getMyDiaryList(long userId, Category category, SortType sortType) { List diaryEntities; if (category == Category.all) { @@ -86,8 +86,8 @@ public List getMyDiaryList(long userId, Category category, Sort return getDiaryResponse(diaryEntities); } - public DiaryListResponse getDiariesResponse(Category category, SortType sortType, boolean isMine, long userId) { - List diaryResponses; + public DiaryListRes getDiariesResponse(Category category, SortType sortType, boolean isMine, long userId) { + List diaryResponses; if (isMine) { diaryResponses = getMyDiaryList(userId, category, sortType); @@ -95,11 +95,8 @@ public DiaryListResponse getDiariesResponse(Category category, SortType sortType diaryResponses = getDiaryList(category, sortType); } - return new DiaryListResponse(diaryResponses); + return new DiaryListRes(diaryResponses); } - - - } diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index 5a446ae..0b615d7 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -1,7 +1,7 @@ package org.sopt.Diary.service; import org.sopt.Diary.dto.req.DiaryReq; -import org.sopt.Diary.dto.res.DiaryResponse; +import org.sopt.Diary.dto.res.DiaryRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.repository.DiaryRepository; @@ -10,21 +10,16 @@ import org.springframework.web.server.ResponseStatusException; -import java.time.Duration; -import java.time.LocalDateTime; @Component public class DiaryService { - private final static int LIMIT_MINUTE = 5; private final DiaryRepository diaryRepository; - public DiaryService(DiaryRepository diaryRepository) { this.diaryRepository = diaryRepository; - } final public void createDiary(final long userId, final DiaryReq diaryRequest) { @@ -39,11 +34,11 @@ final public void createDiary(final long userId, final DiaryReq diaryRequest) { ); } - public DiaryResponse getDiary(final long id) { + public DiaryRes getDiary(final long id) { DiaryEntity diaryEntity = findByDiaryIdPrivateFalse(id); - return new DiaryResponse(diaryEntity.getDiaryId(), + return new DiaryRes(diaryEntity.getDiaryId(), diaryEntity.getTitle(), diaryEntity.getContent(), diaryEntity.getContent(), From ab2f986bc977572a8c937f0d428a4a6fca4945a7 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 14:15:49 +0900 Subject: [PATCH 08/16] =?UTF-8?q?gitignore=20=EC=97=90=20yml=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a63c0a1..f56b8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ build/ .idea/workspace.xml .idea/libraries/ .idea/** -.idea/vcs.xml .idea .idea/ *.iws @@ -55,4 +54,5 @@ bin/ diary.txt *.yml -.yml \ No newline at end of file +.yml +/Users/macbook/Desktop/SOPT/Server/homework/seminar/src/main/resources/application.yml \ No newline at end of file From be88a49173d19219156a28cdd4203b6e32e13aab Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Thu, 31 Oct 2024 16:34:21 +0900 Subject: [PATCH 09/16] =?UTF-8?q?fix:Transactional=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/sopt/Diary/controller/DiaryController.java | 13 +++++++++++++ .../org/sopt/Diary/controller/UserController.java | 9 +++++++++ .../java/org/sopt/Diary/service/DiariesService.java | 6 ++++-- .../java/org/sopt/Diary/service/DiaryService.java | 9 +++++---- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index a39493f..ed66346 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -50,6 +50,13 @@ ResponseEntity getDiary(@PathVariable("diaryId") final long diaryId) { return ResponseEntity.ok(diaryRes); } + /** + * 일기 수정 + * @param userId 유저 아이디 + * @param diaryId 다이어리 아이디 + * @param diaryRequest content,category + * @return 200 + */ @PatchMapping("/{diaryId}") ResponseEntity updateDiary(@RequestHeader("userId") long userId, @PathVariable("diaryId") final long diaryId, @@ -63,6 +70,12 @@ ResponseEntity updateDiary(@RequestHeader("userId") long userId, return ResponseEntity.ok("일기가 수정되었습니다."); } + /** + * 일기 삭제하기 + * @param userId 유저 아이디 + * @param diaryId 다이어리 아이디 + * @return 200 + */ @DeleteMapping("/{diaryId}") ResponseEntity deleteDiary(@RequestHeader("userId") long userId, @PathVariable("diaryId") final long diaryId){ diff --git a/src/main/java/org/sopt/Diary/controller/UserController.java b/src/main/java/org/sopt/Diary/controller/UserController.java index b4626b1..536cba5 100644 --- a/src/main/java/org/sopt/Diary/controller/UserController.java +++ b/src/main/java/org/sopt/Diary/controller/UserController.java @@ -18,6 +18,10 @@ public class UserController { public UserController(final UserService userService){this.userService=userService;} + /** + * 회원가입 + * @param signUpRequest Id, Pwd, Nickname + */ @PostMapping("/signup") private void signUp(@Valid @RequestBody SignUpReq signUpRequest){ // 제약사항 따로 없음 @@ -25,6 +29,11 @@ private void signUp(@Valid @RequestBody SignUpReq signUpRequest){ userService.join(signUpRequest); } + /** + * 로그인 + * @param signInReq Id, Pwd + * @return 200 + */ @PostMapping("/signin") private UserRes signIn(@Valid @RequestBody SignInReq signInReq){ Long userId= userService.login(signInReq); diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index 270f7aa..fa2571a 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -1,5 +1,6 @@ package org.sopt.Diary.service; +import jakarta.transaction.Transactional; import org.sopt.Diary.Formatter.DiaryFormatter; import org.sopt.Diary.dto.res.DiariesRes; import org.sopt.Diary.dto.res.DiaryListRes; @@ -9,13 +10,14 @@ import org.sopt.Diary.entity.UserEntity; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; import java.util.ArrayList; import java.util.List; -@Component +@Transactional +@Service public class DiariesService { private final static int LIMIT_DIARY = 10; diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index 0b615d7..a25a6b1 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -1,18 +1,19 @@ package org.sopt.Diary.service; +import jakarta.transaction.Transactional; import org.sopt.Diary.dto.req.DiaryReq; import org.sopt.Diary.dto.res.DiaryRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; - -import org.springframework.web.server.ResponseStatusException; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; -@Component +@Transactional +@Service public class DiaryService { From 5a934b905515240aaf6da7e5c85e5059743df015 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Fri, 1 Nov 2024 23:32:00 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat(diary)=20:=20=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +-- .../sopt/Diary/controller/DiaryController.java | 6 ++++-- .../java/org/sopt/Diary/entity/DiaryEntity.java | 3 +++ .../DiaryFormatter.java | 2 +- .../sopt/Diary/repository/DiaryRepository.java | 6 +++--- .../org/sopt/Diary/service/DiariesService.java | 10 +++++----- .../org/sopt/Diary/service/DiaryService.java | 17 +++++++++++------ 7 files changed, 28 insertions(+), 19 deletions(-) rename src/main/java/org/sopt/Diary/{Formatter => formatter}/DiaryFormatter.java (92%) diff --git a/.gitignore b/.gitignore index f56b8a9..3e5495e 100644 --- a/.gitignore +++ b/.gitignore @@ -54,5 +54,4 @@ bin/ diary.txt *.yml -.yml -/Users/macbook/Desktop/SOPT/Server/homework/seminar/src/main/resources/application.yml \ No newline at end of file +.yml \ No newline at end of file diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index ed66346..635c8d9 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -16,6 +16,7 @@ public class DiaryController { private final DiaryService diaryService; private final UserService userService; + public DiaryController(DiaryService diaryService,UserService userService) { this.diaryService = diaryService; this.userService=userService; @@ -45,8 +46,9 @@ ResponseEntity postDiary(@RequestHeader("userId") long userId, @Valid @R * @return 200 */ @GetMapping("/{diaryId}") - ResponseEntity getDiary(@PathVariable("diaryId") final long diaryId) { - final DiaryRes diaryRes = diaryService.getDiary(diaryId); + ResponseEntity getDiary(@RequestHeader(name="userId",required = false) Long userId, @PathVariable("diaryId") final long diaryId) { + DiaryRes diaryRes = diaryService.getDiary(userId, diaryId); + return ResponseEntity.ok(diaryRes); } diff --git a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java index 90b462a..6459c54 100644 --- a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -76,5 +76,8 @@ public long getUserId(){ return userId; } + public boolean getIsPrivate() { + return isPrivate; + } } diff --git a/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java b/src/main/java/org/sopt/Diary/formatter/DiaryFormatter.java similarity index 92% rename from src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java rename to src/main/java/org/sopt/Diary/formatter/DiaryFormatter.java index 099b052..056e8aa 100644 --- a/src/main/java/org/sopt/Diary/Formatter/DiaryFormatter.java +++ b/src/main/java/org/sopt/Diary/formatter/DiaryFormatter.java @@ -1,4 +1,4 @@ -package org.sopt.Diary.Formatter; +package org.sopt.Diary.formatter; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java index 7ab478a..ae11de1 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java +++ b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java @@ -5,18 +5,18 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; import java.util.List; import java.util.Optional; -@Component +@Repository public interface DiaryRepository extends JpaRepository { Boolean existsByTitle(String title); - Optional findByIdAndIsPrivateFalse(Long id); + Optional findByIdAndUserId(long DiaryId, long userId); //카테고리 필터링 Optional> findByCategoryAndIsPrivateFalseOrderByCreatedAtDesc(Category category); diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index fa2571a..c02e44f 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -1,7 +1,7 @@ package org.sopt.Diary.service; import jakarta.transaction.Transactional; -import org.sopt.Diary.Formatter.DiaryFormatter; +import org.sopt.Diary.formatter.DiaryFormatter; import org.sopt.Diary.dto.res.DiariesRes; import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; @@ -24,24 +24,24 @@ public class DiariesService { private final DiaryRepository diaryRepository; private final UserService userService; - public DiariesService(DiaryRepository diaryRepository, UserService userService) { + public DiariesService( DiaryRepository diaryRepository, UserService userService) { this.diaryRepository = diaryRepository; this.userService = userService; } private List getDiaryResponse(List diaryEntities) { - List diariesRespons = new ArrayList<>(); + List diariesResponse = new ArrayList<>(); int count =0; for (DiaryEntity diary : diaryEntities) { if(count < LIMIT_DIARY) { final UserEntity user = userService.findByUserId(diary.getUserId()); final String createdAt = DiaryFormatter.dateFormatter(diary.getCreatedAt()); DiariesRes diariesRes = new DiariesRes(diary.getDiaryId(), user.getNickname(), diary.getTitle(), createdAt); - diariesRespons.add(diariesRes); + diariesResponse.add(diariesRes); count++; } } - return diariesRespons; + return diariesResponse; } public List getDiaryList(Category category, SortType sortType) { diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index a25a6b1..d307820 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -12,6 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; + @Transactional @Service public class DiaryService { @@ -35,9 +36,15 @@ final public void createDiary(final long userId, final DiaryReq diaryRequest) { ); } - public DiaryRes getDiary(final long id) { + public DiaryRes getDiary(final Long userId, final long diaryId) { + DiaryEntity diaryEntity = findByDiaryId(diaryId); - DiaryEntity diaryEntity = findByDiaryIdPrivateFalse(id); + //비공개 일기일 경우 + if(diaryEntity.getIsPrivate()) { + if(userId == null || (userId != diaryEntity.getUserId())){ + throw new ResponseStatusException(HttpStatus.FORBIDDEN); + } + } return new DiaryRes(diaryEntity.getDiaryId(), diaryEntity.getTitle(), @@ -46,6 +53,7 @@ public DiaryRes getDiary(final long id) { diaryEntity.getCategory()); } + public void patchDiary(final long userId, final long diaryId, final String content, final Category category) { DiaryEntity diaryEntity = findByDiaryId(diaryId); @@ -76,10 +84,6 @@ public DiaryEntity findByDiaryId(final long id){ .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,"일기를 찾을 수 없습니다")); } - public DiaryEntity findByDiaryIdPrivateFalse(final long id){ - return diaryRepository.findByIdAndIsPrivateFalse(id) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,"일기를 찾을 수 없습니다")); - } public void validateTitle(final String title){ if(diaryRepository.existsByTitle(title)){ @@ -87,4 +91,5 @@ public void validateTitle(final String title){ } } + } \ No newline at end of file From 4899d64ce2bbcc5c6ed12325e4b49220769fcc38 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Fri, 1 Nov 2024 23:35:02 +0900 Subject: [PATCH 11/16] =?UTF-8?q?yml=ED=8C=8C=EC=9D=BC=20gitignore?= =?UTF-8?q?=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/main/resources/application.yml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index 2c003ff..0000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,14 +0,0 @@ -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/seminar3 - username: root - password: 12345678 - jpa: - show-sql: true - hibernate: - ddl-auto: update - dialect: org.hibernate.dialect.MySQL8Dialect - properties: - format_sql: true - show_sql: true \ No newline at end of file From 88166c25634521ec5df2274148581d3e92b82393 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Sun, 3 Nov 2024 01:26:30 +0900 Subject: [PATCH 12/16] =?UTF-8?q?feat(diaries)=20:=20diary=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Diary/controller/DiariesController.java | 12 +- .../org/sopt/Diary/entity/DiaryEntity.java | 11 +- .../Diary/repository/DiaryRepository.java | 39 +------ .../sopt/Diary/service/DiariesService.java | 106 ++++++++---------- .../org/sopt/Diary/service/DiaryService.java | 5 +- 5 files changed, 70 insertions(+), 103 deletions(-) diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java index f62b05a..9d372a9 100644 --- a/src/main/java/org/sopt/Diary/controller/DiariesController.java +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -1,5 +1,6 @@ package org.sopt.Diary.controller; +import org.sopt.Diary.dto.res.DiariesRes; import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.SortType; @@ -7,6 +8,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RequestMapping("/diaries") @RestController public class DiariesController { @@ -20,20 +23,21 @@ public DiariesController(DiariesService diariesService) { @GetMapping() public ResponseEntity getDiaries( - @RequestParam(name = "category") final Category category, + @RequestHeader(name="userId" , required = false) Long userId, + @RequestParam(name = "category" , required = false, defaultValue = "all") final Category category, @RequestParam(name = "sort",required = false, defaultValue = "latest") final SortType sortType) { - DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType, false, 0); + DiaryListRes diaryListRes = diariesService.getDiariesResponse( category,sortType, false, userId); return ResponseEntity.ok(diaryListRes); } @GetMapping("/my") public ResponseEntity getMyDiaries( @RequestHeader("userId") long userId, - @RequestParam(name = "category") final Category category, + @RequestParam(name = "category",required = false, defaultValue = "all") final Category category, @RequestParam(name = "sort",required = false, defaultValue = "latest")final SortType sortType) { - DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType, true, userId); + DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType,true,userId); return ResponseEntity.ok(diaryListRes); } } diff --git a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java index 6459c54..22d80d9 100644 --- a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -36,7 +36,7 @@ public class DiaryEntity { //JPA 는 엔티티 객체를 생성할때 기본 생성자를 사용하므로 반드시 있어야 한다! public DiaryEntity() {} - public DiaryEntity(final String title,final String content,final Category category,final boolean isPrivate,final long userId) { + public DiaryEntity(final String title,final String content,final Category category,final boolean isPrivate,final Long userId) { this.title = title; this.content = content; this.category = category; @@ -44,6 +44,11 @@ public DiaryEntity(final String title,final String content,final Category catego this.userId = userId; } + public static DiaryEntity of (final String title,final String content,final Category category,final boolean isPrivate,final long userId) { + return new DiaryEntity(title, content, category, isPrivate, userId); + } + + public DiaryEntity(final long id, final String title, final String content, final LocalDateTime createdAt, final Category category,final long userId) { this. id = id; @@ -54,7 +59,7 @@ public DiaryEntity(final long id, final String title, final String content, fina this.userId= userId; } - public long getDiaryId(){ + public Long getDiaryId(){ return id; } @@ -72,7 +77,7 @@ public LocalDateTime getCreatedAt() { public Category getCategory(){ return category; } - public long getUserId(){ + public Long getUserId(){ return userId; } diff --git a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java index ae11de1..dfdeeb1 100644 --- a/src/main/java/org/sopt/Diary/repository/DiaryRepository.java +++ b/src/main/java/org/sopt/Diary/repository/DiaryRepository.java @@ -1,47 +1,20 @@ package org.sopt.Diary.repository; -import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; +import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Optional; @Repository -public interface DiaryRepository extends JpaRepository { - +public interface DiaryRepository extends JpaRepository { Boolean existsByTitle(String title); - Optional findByIdAndUserId(long DiaryId, long userId); - - //카테고리 필터링 - Optional> findByCategoryAndIsPrivateFalseOrderByCreatedAtDesc(Category category); - - @Query("SELECT d FROM DiaryEntity d WHERE d.category = :category AND d.isPrivate = false ORDER BY LENGTH(d.content) DESC") - Optional> findByCategoryAndIsPrivateFalseOrderByContentLengthDesc(@Param("category") Category category); - - - //카테고리 필터링 - MyDiary - Optional> findByUserIdAndCategoryOrderByCreatedAtDesc(long userId, Category category); - - @Query("SELECT d FROM DiaryEntity d WHERE d.category = :category AND d.userId = :userId ORDER BY LENGTH(d.content) DESC") - Optional> findByUserIdAndCategoryOrderByContentLengthDesc(@Param("userId") long userId, @Param("category") Category category); - - - //카테고리 필터링 X - 전체 조회 - Optional> findAllByIsPrivateFalseOrderByCreatedAtDesc(); - - @Query("SELECT d FROM DiaryEntity d WHERE d.isPrivate = false ORDER BY LENGTH(d.content) DESC") - Optional> findAllByIsPrivateFalseOrderByContentLengthDesc(); - + List findAllByIsPrivateFalse(); - //카테고리 필터링 X - MyDiary - @Query("SELECT d FROM DiaryEntity d WHERE d.userId = :userId ORDER BY LENGTH(d.content) DESC") - Optional> findByUserIdOrderByContentLengthDesc(@Param("userId") long userId); + // 필수적으로 UserId 필요 + List findByUserId(long userId); - Optional> findByUserIdOrderByCreatedAtDesc(@Param("userId") long userId); + List findByUserIdOrIsPrivateFalse(Long userId); } diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index c02e44f..b710f30 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -1,9 +1,9 @@ package org.sopt.Diary.service; import jakarta.transaction.Transactional; +import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.formatter.DiaryFormatter; import org.sopt.Diary.dto.res.DiariesRes; -import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; import org.sopt.Diary.entity.SortType; @@ -13,8 +13,9 @@ import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; -import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; @Transactional @Service @@ -24,80 +25,63 @@ public class DiariesService { private final DiaryRepository diaryRepository; private final UserService userService; - public DiariesService( DiaryRepository diaryRepository, UserService userService) { + public DiariesService(DiaryRepository diaryRepository, UserService userService) { this.diaryRepository = diaryRepository; this.userService = userService; } - private List getDiaryResponse(List diaryEntities) { - List diariesResponse = new ArrayList<>(); - int count =0; - for (DiaryEntity diary : diaryEntities) { - if(count < LIMIT_DIARY) { - final UserEntity user = userService.findByUserId(diary.getUserId()); - final String createdAt = DiaryFormatter.dateFormatter(diary.getCreatedAt()); - DiariesRes diariesRes = new DiariesRes(diary.getDiaryId(), user.getNickname(), diary.getTitle(), createdAt); - diariesResponse.add(diariesRes); - count++; - } - } - return diariesResponse; - } - - public List getDiaryList(Category category, SortType sortType) { + public DiaryListRes getDiariesResponse(Category category, SortType sortType, boolean isMine, Long userId) { List diaryEntities; - if (category == Category.all) { - diaryEntities = switch (sortType) { - case latest -> diaryRepository.findAllByIsPrivateFalseOrderByCreatedAtDesc() - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - case quantity -> diaryRepository.findAllByIsPrivateFalseOrderByContentLengthDesc() - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - }; + if (isMine) { + // /my 로 들어온 경우 - 내가 쓴 일기만 조회 + diaryEntities = diaryRepository.findByUserId(userId); + } else if (userId == null) { + // userId 없는 경우 - 공개된 일기만 조회 + diaryEntities = diaryRepository.findAllByIsPrivateFalse(); } else { - diaryEntities = switch (sortType) { - case latest -> diaryRepository.findByCategoryAndIsPrivateFalseOrderByCreatedAtDesc(category) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - case quantity -> diaryRepository.findByCategoryAndIsPrivateFalseOrderByContentLengthDesc(category) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - }; + // userId가 null 이 아닌 경우, 해당 user 의 일기와 isPrivateFalse 인 일기가 보이도록 + diaryEntities = diaryRepository.findByUserIdOrIsPrivateFalse(userId); } - return getDiaryResponse(diaryEntities); - } - - public List getMyDiaryList(long userId, Category category, SortType sortType) { - List diaryEntities; - if (category == Category.all) { - diaryEntities = switch (sortType) { - case latest -> diaryRepository.findByUserIdOrderByCreatedAtDesc(userId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - case quantity -> diaryRepository.findByUserIdOrderByContentLengthDesc(userId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); + // Optional 로 처리하지 않은 이유 : 위에서 공통적인 에러 발생할 예정이라 한 번에 처리하려고 + if(diaryEntities==null){ + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } - }; - } else { - diaryEntities = switch (sortType) { - case latest -> diaryRepository.findByUserIdAndCategoryOrderByCreatedAtDesc(userId, category) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - case quantity -> diaryRepository.findByUserIdAndCategoryOrderByContentLengthDesc(userId, category) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "일기를 찾을 수 없습니다")); - }; + // 선택된 카테고리에 따라 필터링 + if (category != Category.all) { + diaryEntities = diaryEntities.stream() + .filter(diary -> diary.getCategory() == category) + .collect(Collectors.toList()); } - return getDiaryResponse(diaryEntities); - } + // sortType 에 따른 필터링 + Comparator comparator = getComparator(sortType); + diaryEntities = diaryEntities.stream() + .sorted(comparator) + .limit(LIMIT_DIARY) // 10개 제한 + .collect(Collectors.toList()); - public DiaryListRes getDiariesResponse(Category category, SortType sortType, boolean isMine, long userId) { - List diaryResponses; + return new DiaryListRes(getDiaryResponse(diaryEntities)); + } - if (isMine) { - diaryResponses = getMyDiaryList(userId, category, sortType); - } else { - diaryResponses = getDiaryList(category, sortType); - } + private Comparator getComparator(SortType sortType) { + return switch (sortType) { + case latest -> Comparator.comparing(DiaryEntity::getCreatedAt).reversed(); // 최신 순 정렬 + case quantity -> Comparator.comparingInt((DiaryEntity diary) -> diary.getContent().length()).reversed(); // 내용 길이 기준 내림차순 정렬 + }; + } - return new DiaryListRes(diaryResponses); + // userNickName, date 형식 변환을 위한 메소드 + private List getDiaryResponse(List diaryEntities) { + return diaryEntities.stream() + .map(diary -> { + final UserEntity user = userService.findByUserId(diary.getUserId()); + final String createdAt = DiaryFormatter.dateFormatter(diary.getCreatedAt()); + return new DiariesRes(diary.getDiaryId(), user.getNickname(), diary.getTitle(), createdAt); + }) + .collect(Collectors.toList()); } } diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index d307820..a781324 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -37,11 +37,12 @@ final public void createDiary(final long userId, final DiaryReq diaryRequest) { } public DiaryRes getDiary(final Long userId, final long diaryId) { + DiaryEntity diaryEntity = findByDiaryId(diaryId); - //비공개 일기일 경우 + //비공개 일기일 경우 = userId 검증 if(diaryEntity.getIsPrivate()) { - if(userId == null || (userId != diaryEntity.getUserId())){ + if( userId != diaryEntity.getUserId()){ throw new ResponseStatusException(HttpStatus.FORBIDDEN); } } From 55a7631d0f84cba1d863364f366ca877f2795ea0 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Sun, 3 Nov 2024 03:58:41 +0900 Subject: [PATCH 13/16] =?UTF-8?q?fix(error):=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +++ .../org/sopt/Diary/error/CustomException.java | 16 ++++++++++ .../java/org/sopt/Diary/error/ErrorCode.java | 32 +++++++++++++++++++ .../org/sopt/Diary/error/ErrorResponse.java | 13 ++++++++ .../Diary/error/GlobalExceptionHandler.java | 18 +++++++++++ .../sopt/Diary/service/DiariesService.java | 7 ++-- .../org/sopt/Diary/service/DiaryService.java | 12 ++++--- .../org/sopt/Diary/service/UserService.java | 8 +++-- .../sopt/Diary/validator/DiaryValidator.java | 8 ++--- 9 files changed, 104 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/sopt/Diary/error/CustomException.java create mode 100644 src/main/java/org/sopt/Diary/error/ErrorCode.java create mode 100644 src/main/java/org/sopt/Diary/error/ErrorResponse.java create mode 100644 src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java diff --git a/build.gradle b/build.gradle index 8fa02bc..74134e1 100644 --- a/build.gradle +++ b/build.gradle @@ -18,12 +18,17 @@ java { } dependencies { + + compileOnly 'org.projectlombok:lombok:1.18.30' + annotationProcessor 'org.projectlombok:lombok:1.18.30' + implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.junit.platform:junit-platform-launcher' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'com.h2database:h2' runtimeOnly 'mysql:mysql-connector-java:8.0.32' diff --git a/src/main/java/org/sopt/Diary/error/CustomException.java b/src/main/java/org/sopt/Diary/error/CustomException.java new file mode 100644 index 0000000..6f9c2d7 --- /dev/null +++ b/src/main/java/org/sopt/Diary/error/CustomException.java @@ -0,0 +1,16 @@ +package org.sopt.Diary.error; + +import lombok.Getter; + +@Getter +public class CustomException extends RuntimeException{ + // 서비스 레이어에서 주로 사용하기 위한 예외 + // HTTP 응답에 직접적으로 영향을 미치지 않기 때문에, 구체적인 예외 처리 정의 후 처리 + + private ErrorCode errorCode; + + public CustomException(ErrorCode errorCode){ + super(errorCode.getMessage()); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/org/sopt/Diary/error/ErrorCode.java b/src/main/java/org/sopt/Diary/error/ErrorCode.java new file mode 100644 index 0000000..b2397f2 --- /dev/null +++ b/src/main/java/org/sopt/Diary/error/ErrorCode.java @@ -0,0 +1,32 @@ +package org.sopt.Diary.error; + +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +public enum ErrorCode { + + //user + ALREADY_EXIST_USER(HttpStatus.CONFLICT, "USER001", "이미 존재하는 사용자입니다."), + INVALID_USER(HttpStatus.NOT_FOUND, "USER002", "존재하지 않는 사용자입니다."), + BAD_REQUEST(HttpStatus.BAD_REQUEST, "USER004", "로그인 정보가 올바르지 않습니다."), + + //diary + INVALID_INPUT_LENGTH(HttpStatus.LENGTH_REQUIRED, "diary001", "글자수를 다시 확인해주세요"), + ACCESS_DENIED(HttpStatus.FORBIDDEN, "diary002", "접근 권한이 없습니다"), + DIARY_NOT_FOUND(HttpStatus.NOT_FOUND, "diary003", "일기를 찾을 수 없습니다."), + DUPLICATE_TITLE(HttpStatus.NOT_FOUND, "diary004", "이미 있는 제목입니다."); + + + + private HttpStatus status; + private final String code; + private final String message; + + ErrorCode(HttpStatus status, String code, String message) { + this.status = status; + this.code = code; + this.message = message; + } + +} diff --git a/src/main/java/org/sopt/Diary/error/ErrorResponse.java b/src/main/java/org/sopt/Diary/error/ErrorResponse.java new file mode 100644 index 0000000..5797e9b --- /dev/null +++ b/src/main/java/org/sopt/Diary/error/ErrorResponse.java @@ -0,0 +1,13 @@ +package org.sopt.Diary.error; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public class ErrorResponse { + private final HttpStatus httpStatus; + private final String code; + private final String error; +} diff --git a/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java b/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java new file mode 100644 index 0000000..69c25f0 --- /dev/null +++ b/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java @@ -0,0 +1,18 @@ +package org.sopt.Diary.error; + + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(CustomException.class) + public ResponseEntity handleCustomException(CustomException ex){ + ErrorResponse response = new ErrorResponse(ex.getErrorCode().getStatus(), ex.getErrorCode().getCode(), ex.getMessage()); + return new ResponseEntity<>(response, HttpStatus.valueOf(String.valueOf(ex.getErrorCode().getStatus()))); + } + +} diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index b710f30..40b0a3c 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -2,6 +2,8 @@ import jakarta.transaction.Transactional; import org.sopt.Diary.dto.res.DiaryListRes; +import org.sopt.Diary.error.CustomException; +import org.sopt.Diary.error.ErrorCode; import org.sopt.Diary.formatter.DiaryFormatter; import org.sopt.Diary.dto.res.DiariesRes; import org.sopt.Diary.entity.Category; @@ -9,9 +11,8 @@ import org.sopt.Diary.entity.SortType; import org.sopt.Diary.entity.UserEntity; import org.sopt.Diary.repository.DiaryRepository; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; -import org.springframework.web.server.ResponseStatusException; + import java.util.Comparator; import java.util.List; @@ -46,7 +47,7 @@ public DiaryListRes getDiariesResponse(Category category, SortType sortType, boo // Optional 로 처리하지 않은 이유 : 위에서 공통적인 에러 발생할 예정이라 한 번에 처리하려고 if(diaryEntities==null){ - throw new ResponseStatusException(HttpStatus.NOT_FOUND); + throw new CustomException(ErrorCode.DIARY_NOT_FOUND); } // 선택된 카테고리에 따라 필터링 diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index a781324..f24973f 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -5,6 +5,8 @@ import org.sopt.Diary.dto.res.DiaryRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.DiaryEntity; +import org.sopt.Diary.error.CustomException; +import org.sopt.Diary.error.ErrorCode; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.http.HttpStatus; @@ -43,7 +45,7 @@ public DiaryRes getDiary(final Long userId, final long diaryId) { //비공개 일기일 경우 = userId 검증 if(diaryEntity.getIsPrivate()) { if( userId != diaryEntity.getUserId()){ - throw new ResponseStatusException(HttpStatus.FORBIDDEN); + throw new CustomException(ErrorCode.ACCESS_DENIED); } } @@ -60,7 +62,7 @@ public void patchDiary(final long userId, final long diaryId, final String conte DiaryEntity diaryEntity = findByDiaryId(diaryId); if(diaryEntity.getUserId()!=userId){ - throw new ResponseStatusException(HttpStatus.FORBIDDEN); + throw new CustomException(ErrorCode.ACCESS_DENIED); } diaryRepository.save(new DiaryEntity(diaryEntity.getDiaryId(), diaryEntity.getTitle(), @@ -75,20 +77,20 @@ public void deleteDiary(final long userId, final long diaryId) { DiaryEntity diaryEntity= findByDiaryId(diaryId); if(diaryEntity.getUserId()!=userId){ - throw new ResponseStatusException(HttpStatus.FORBIDDEN); + throw new CustomException(ErrorCode.ACCESS_DENIED); } diaryRepository.delete(diaryEntity); } public DiaryEntity findByDiaryId(final long id){ return diaryRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,"일기를 찾을 수 없습니다")); + .orElseThrow(() -> new CustomException(ErrorCode.DIARY_NOT_FOUND)); } public void validateTitle(final String title){ if(diaryRepository.existsByTitle(title)){ - throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"중복된 제목은 불가능 합니다."); + throw new CustomException(ErrorCode.DUPLICATE_TITLE); } } diff --git a/src/main/java/org/sopt/Diary/service/UserService.java b/src/main/java/org/sopt/Diary/service/UserService.java index dcf7ddb..b239176 100644 --- a/src/main/java/org/sopt/Diary/service/UserService.java +++ b/src/main/java/org/sopt/Diary/service/UserService.java @@ -6,6 +6,8 @@ import org.sopt.Diary.dto.req.SignUpReq; import org.sopt.Diary.entity.UserEntity; +import org.sopt.Diary.error.CustomException; +import org.sopt.Diary.error.ErrorCode; import org.sopt.Diary.repository.UserRepository; import org.springframework.stereotype.Service; @@ -31,7 +33,7 @@ public void join(@Valid final SignUpReq signUpRequest) { private void validateDuplicateMember(final String loginId, final String password) { Optional findUser = userRepository.findByLoginIdAndPassword(loginId, password); if(findUser.isPresent()){ - throw new IllegalStateException("이미 존재하는 회원입니다"); + throw new CustomException(ErrorCode.ALREADY_EXIST_USER); } } @@ -39,7 +41,7 @@ public Long login(@Valid final SignInReq signInReq) { // 1. userRepository 에서 Id 찾기 -> NPE 방지 위해 Optional 사용 UserEntity findUser = userRepository.findByLoginIdAndPassword(signInReq.loginId(), signInReq.password()) - .orElseThrow(()-> new IllegalStateException("로그인 정보가 올바르지 않습니다")); + .orElseThrow(()-> new CustomException(ErrorCode.BAD_REQUEST)); // 2. UserID 반환 return findUser.getId(); } @@ -47,7 +49,7 @@ public Long login(@Valid final SignInReq signInReq) { // UserService.java public UserEntity findByUserId(final long userId) { return userRepository.findById(userId) - .orElseThrow(() -> new IllegalStateException("존재하지 않는 사용자입니다.")); + .orElseThrow(() -> new CustomException(ErrorCode.INVALID_USER)); } } diff --git a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java index d782659..245a917 100644 --- a/src/main/java/org/sopt/Diary/validator/DiaryValidator.java +++ b/src/main/java/org/sopt/Diary/validator/DiaryValidator.java @@ -1,8 +1,8 @@ package org.sopt.Diary.validator; -import org.springframework.http.HttpStatus; +import org.sopt.Diary.error.CustomException; +import org.sopt.Diary.error.ErrorCode; import org.springframework.stereotype.Component; -import org.springframework.web.server.ResponseStatusException; @Component public class DiaryValidator { @@ -12,13 +12,13 @@ public class DiaryValidator { public static void checkContent(String content) { if(content.length() > CONTENT_LIMIT || content.isEmpty()){ - throw new ResponseStatusException(HttpStatus.LENGTH_REQUIRED, "내용 글자 수는 1~30자가 되어야 합니다"); + throw new CustomException(ErrorCode.INVALID_INPUT_LENGTH); } } public static void checkTitle(String title) { if(title.length() > TITLE_LIMIT || title.isEmpty()){ - throw new ResponseStatusException(HttpStatus.LENGTH_REQUIRED, "제목 글자 수는 1~10자가 되어야 합니다"); + throw new CustomException(ErrorCode.INVALID_INPUT_LENGTH); } } } From c8507cdaf8cf008b11f057fa41782b240e73bea0 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Sun, 3 Nov 2024 04:17:29 +0900 Subject: [PATCH 14/16] =?UTF-8?q?lombok=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 --- .../Diary/controller/DiariesController.java | 3 --- .../org/sopt/Diary/error/CustomException.java | 7 +++--- .../java/org/sopt/Diary/error/ErrorCode.java | 14 ++++++++++-- .../org/sopt/Diary/error/ErrorResponse.java | 22 +++++++++++++++---- .../Diary/error/GlobalExceptionHandler.java | 10 ++++----- .../org/sopt/Diary/service/DiaryService.java | 4 ---- 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/build.gradle b/build.gradle index 74134e1..8ec9292 100644 --- a/build.gradle +++ b/build.gradle @@ -19,9 +19,6 @@ java { dependencies { - compileOnly 'org.projectlombok:lombok:1.18.30' - annotationProcessor 'org.projectlombok:lombok:1.18.30' - implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java index 9d372a9..8e0ee8f 100644 --- a/src/main/java/org/sopt/Diary/controller/DiariesController.java +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -1,6 +1,5 @@ package org.sopt.Diary.controller; -import org.sopt.Diary.dto.res.DiariesRes; import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.SortType; @@ -8,7 +7,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.util.List; @RequestMapping("/diaries") @RestController @@ -20,7 +18,6 @@ public DiariesController(DiariesService diariesService) { this.diariesService = diariesService; } - @GetMapping() public ResponseEntity getDiaries( @RequestHeader(name="userId" , required = false) Long userId, diff --git a/src/main/java/org/sopt/Diary/error/CustomException.java b/src/main/java/org/sopt/Diary/error/CustomException.java index 6f9c2d7..d943732 100644 --- a/src/main/java/org/sopt/Diary/error/CustomException.java +++ b/src/main/java/org/sopt/Diary/error/CustomException.java @@ -1,8 +1,5 @@ package org.sopt.Diary.error; -import lombok.Getter; - -@Getter public class CustomException extends RuntimeException{ // 서비스 레이어에서 주로 사용하기 위한 예외 // HTTP 응답에 직접적으로 영향을 미치지 않기 때문에, 구체적인 예외 처리 정의 후 처리 @@ -13,4 +10,8 @@ public CustomException(ErrorCode errorCode){ super(errorCode.getMessage()); this.errorCode = errorCode; } + + public ErrorCode getErrorCode() { + return errorCode; + } } diff --git a/src/main/java/org/sopt/Diary/error/ErrorCode.java b/src/main/java/org/sopt/Diary/error/ErrorCode.java index b2397f2..9e0c5a2 100644 --- a/src/main/java/org/sopt/Diary/error/ErrorCode.java +++ b/src/main/java/org/sopt/Diary/error/ErrorCode.java @@ -1,9 +1,8 @@ package org.sopt.Diary.error; -import lombok.Getter; import org.springframework.http.HttpStatus; -@Getter + public enum ErrorCode { //user @@ -29,4 +28,15 @@ public enum ErrorCode { this.message = message; } + public HttpStatus getStatus() { + return status; + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } } diff --git a/src/main/java/org/sopt/Diary/error/ErrorResponse.java b/src/main/java/org/sopt/Diary/error/ErrorResponse.java index 5797e9b..53a5dc2 100644 --- a/src/main/java/org/sopt/Diary/error/ErrorResponse.java +++ b/src/main/java/org/sopt/Diary/error/ErrorResponse.java @@ -1,13 +1,27 @@ package org.sopt.Diary.error; -import lombok.AllArgsConstructor; -import lombok.Getter; import org.springframework.http.HttpStatus; -@Getter -@AllArgsConstructor public class ErrorResponse { private final HttpStatus httpStatus; private final String code; private final String error; + + public HttpStatus getHttpStatus() { + return httpStatus; + } + + public String getCode() { + return code; + } + + public String getError() { + return error; + } + + public ErrorResponse(HttpStatus httpStatus, String code, String error) { + this.httpStatus = httpStatus; + this.code = code; + this.error = error; + } } diff --git a/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java b/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java index 69c25f0..11a2245 100644 --- a/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java +++ b/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java @@ -1,7 +1,5 @@ package org.sopt.Diary.error; - -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -11,8 +9,10 @@ public class GlobalExceptionHandler { @ExceptionHandler(CustomException.class) public ResponseEntity handleCustomException(CustomException ex){ - ErrorResponse response = new ErrorResponse(ex.getErrorCode().getStatus(), ex.getErrorCode().getCode(), ex.getMessage()); - return new ResponseEntity<>(response, HttpStatus.valueOf(String.valueOf(ex.getErrorCode().getStatus()))); + ErrorResponse response = new ErrorResponse( + ex.getErrorCode().getStatus(), + ex.getErrorCode().getCode(), + ex.getErrorCode().getMessage()); + return new ResponseEntity<>(response,ex.getErrorCode().getStatus()); } - } diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index f24973f..adb9a71 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -8,11 +8,7 @@ import org.sopt.Diary.error.CustomException; import org.sopt.Diary.error.ErrorCode; import org.sopt.Diary.repository.DiaryRepository; -import org.springframework.http.HttpStatus; - - import org.springframework.stereotype.Service; -import org.springframework.web.server.ResponseStatusException; @Transactional From 8ac8e14414961b4be838f5b20b87617cd2f7a18e Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Sun, 3 Nov 2024 14:41:42 +0900 Subject: [PATCH 15/16] =?UTF-8?q?fix(service)=20:=20@Transactional=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Diary/controller/DiariesController.java | 5 +++-- .../sopt/Diary/controller/DiaryController.java | 4 ++-- .../org/sopt/Diary/entity/DiaryEntity.java | 2 +- .../Diary/error/GlobalExceptionHandler.java | 6 ++++++ .../sopt/Diary/repository/UserRepository.java | 1 + .../org/sopt/Diary/service/DiariesService.java | 13 +++---------- .../org/sopt/Diary/service/DiaryService.java | 10 ++++++---- .../org/sopt/Diary/service/UserService.java | 18 +++++++++--------- 8 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java index 8e0ee8f..b1060a5 100644 --- a/src/main/java/org/sopt/Diary/controller/DiariesController.java +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -1,5 +1,6 @@ package org.sopt.Diary.controller; +import jakarta.validation.Valid; import org.sopt.Diary.dto.res.DiaryListRes; import org.sopt.Diary.entity.Category; import org.sopt.Diary.entity.SortType; @@ -30,8 +31,8 @@ public ResponseEntity getDiaries( @GetMapping("/my") public ResponseEntity getMyDiaries( - @RequestHeader("userId") long userId, - @RequestParam(name = "category",required = false, defaultValue = "all") final Category category, + @Valid @RequestHeader("userId") long userId, + @Valid @RequestParam(name = "category",required = false, defaultValue = "all") final Category category, @RequestParam(name = "sort",required = false, defaultValue = "latest")final SortType sortType) { DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType,true,userId); diff --git a/src/main/java/org/sopt/Diary/controller/DiaryController.java b/src/main/java/org/sopt/Diary/controller/DiaryController.java index 635c8d9..04c16af 100644 --- a/src/main/java/org/sopt/Diary/controller/DiaryController.java +++ b/src/main/java/org/sopt/Diary/controller/DiaryController.java @@ -60,8 +60,8 @@ ResponseEntity getDiary(@RequestHeader(name="userId",required = false) * @return 200 */ @PatchMapping("/{diaryId}") - ResponseEntity updateDiary(@RequestHeader("userId") long userId, - @PathVariable("diaryId") final long diaryId, + ResponseEntity updateDiary( @RequestHeader("userId") long userId, + @PathVariable("diaryId") final long diaryId, @Valid @RequestBody DiaryUpdateReq diaryRequest){ //UserId, 내용 글자수 검증 diff --git a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java index 22d80d9..ac853e6 100644 --- a/src/main/java/org/sopt/Diary/entity/DiaryEntity.java +++ b/src/main/java/org/sopt/Diary/entity/DiaryEntity.java @@ -13,7 +13,7 @@ public class DiaryEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name="title") + @Column(name="title",unique = true) private String title; @Column(name="content") diff --git a/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java b/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java index 11a2245..462313f 100644 --- a/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java +++ b/src/main/java/org/sopt/Diary/error/GlobalExceptionHandler.java @@ -4,9 +4,15 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +/* +전역적으로 에러를 처리해준다. +@ControllerAdvice 에 @ResponseBody 추가 된 형태 +@ControllerAdvice는 @ExceptionHandler 에 기능을 부여해주는 역할 +*/ @RestControllerAdvice public class GlobalExceptionHandler { + //특정 에러 발생 시 Controller에 발생하였을 경우 해당 에러를 캐치하여 클라이언트로 오류를 반환하도록 처리하는 기능을 수행 @ExceptionHandler(CustomException.class) public ResponseEntity handleCustomException(CustomException ex){ ErrorResponse response = new ErrorResponse( diff --git a/src/main/java/org/sopt/Diary/repository/UserRepository.java b/src/main/java/org/sopt/Diary/repository/UserRepository.java index d5750ab..c885d91 100644 --- a/src/main/java/org/sopt/Diary/repository/UserRepository.java +++ b/src/main/java/org/sopt/Diary/repository/UserRepository.java @@ -7,4 +7,5 @@ public interface UserRepository extends JpaRepository { Optional findByLoginIdAndPassword(String loginId, String password); + // Null 이 올 수 있는 객체는 Optional 을 통해 감싸줌 } diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index 40b0a3c..df50522 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -1,9 +1,6 @@ package org.sopt.Diary.service; -import jakarta.transaction.Transactional; import org.sopt.Diary.dto.res.DiaryListRes; -import org.sopt.Diary.error.CustomException; -import org.sopt.Diary.error.ErrorCode; import org.sopt.Diary.formatter.DiaryFormatter; import org.sopt.Diary.dto.res.DiariesRes; import org.sopt.Diary.entity.Category; @@ -12,13 +9,13 @@ import org.sopt.Diary.entity.UserEntity; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.stereotype.Service; - +import org.springframework.transaction.annotation.Transactional; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; -@Transactional +@Transactional(readOnly=true) @Service public class DiariesService { @@ -31,6 +28,7 @@ public DiariesService(DiaryRepository diaryRepository, UserService userService) this.userService = userService; } + public DiaryListRes getDiariesResponse(Category category, SortType sortType, boolean isMine, Long userId) { List diaryEntities; @@ -45,11 +43,6 @@ public DiaryListRes getDiariesResponse(Category category, SortType sortType, boo diaryEntities = diaryRepository.findByUserIdOrIsPrivateFalse(userId); } - // Optional 로 처리하지 않은 이유 : 위에서 공통적인 에러 발생할 예정이라 한 번에 처리하려고 - if(diaryEntities==null){ - throw new CustomException(ErrorCode.DIARY_NOT_FOUND); - } - // 선택된 카테고리에 따라 필터링 if (category != Category.all) { diaryEntities = diaryEntities.stream() diff --git a/src/main/java/org/sopt/Diary/service/DiaryService.java b/src/main/java/org/sopt/Diary/service/DiaryService.java index adb9a71..626df9f 100644 --- a/src/main/java/org/sopt/Diary/service/DiaryService.java +++ b/src/main/java/org/sopt/Diary/service/DiaryService.java @@ -1,6 +1,6 @@ package org.sopt.Diary.service; -import jakarta.transaction.Transactional; + import org.sopt.Diary.dto.req.DiaryReq; import org.sopt.Diary.dto.res.DiaryRes; import org.sopt.Diary.entity.Category; @@ -9,9 +9,9 @@ import org.sopt.Diary.error.ErrorCode; import org.sopt.Diary.repository.DiaryRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; - -@Transactional +@Transactional(readOnly=true) @Service public class DiaryService { @@ -22,6 +22,7 @@ public DiaryService(DiaryRepository diaryRepository) { this.diaryRepository = diaryRepository; } + @Transactional final public void createDiary(final long userId, final DiaryReq diaryRequest) { validateTitle(diaryRequest.title()); @@ -52,7 +53,7 @@ public DiaryRes getDiary(final Long userId, final long diaryId) { diaryEntity.getCategory()); } - + @Transactional public void patchDiary(final long userId, final long diaryId, final String content, final Category category) { DiaryEntity diaryEntity = findByDiaryId(diaryId); @@ -68,6 +69,7 @@ public void patchDiary(final long userId, final long diaryId, final String conte diaryEntity.getUserId())); } + @Transactional public void deleteDiary(final long userId, final long diaryId) { DiaryEntity diaryEntity= findByDiaryId(diaryId); diff --git a/src/main/java/org/sopt/Diary/service/UserService.java b/src/main/java/org/sopt/Diary/service/UserService.java index b239176..3439c0b 100644 --- a/src/main/java/org/sopt/Diary/service/UserService.java +++ b/src/main/java/org/sopt/Diary/service/UserService.java @@ -1,10 +1,10 @@ package org.sopt.Diary.service; -import jakarta.transaction.Transactional; + import jakarta.validation.Valid; import org.sopt.Diary.dto.req.SignInReq; import org.sopt.Diary.dto.req.SignUpReq; - +import org.springframework.transaction.annotation.Transactional; import org.sopt.Diary.entity.UserEntity; import org.sopt.Diary.error.CustomException; import org.sopt.Diary.error.ErrorCode; @@ -30,13 +30,6 @@ public void join(@Valid final SignUpReq signUpRequest) { userRepository.save(newUserEntity); } - private void validateDuplicateMember(final String loginId, final String password) { - Optional findUser = userRepository.findByLoginIdAndPassword(loginId, password); - if(findUser.isPresent()){ - throw new CustomException(ErrorCode.ALREADY_EXIST_USER); - } - } - public Long login(@Valid final SignInReq signInReq) { // 1. userRepository 에서 Id 찾기 -> NPE 방지 위해 Optional 사용 @@ -52,4 +45,11 @@ public UserEntity findByUserId(final long userId) { .orElseThrow(() -> new CustomException(ErrorCode.INVALID_USER)); } + private void validateDuplicateMember(final String loginId, final String password) { + Optional findUser = userRepository.findByLoginIdAndPassword(loginId, password); + if(findUser.isPresent()){ + throw new CustomException(ErrorCode.ALREADY_EXIST_USER); + } + } + } From 3d351f8849b1d24c484529b9c7346d483f399186 Mon Sep 17 00:00:00 2001 From: jjuny-won Date: Mon, 4 Nov 2024 23:21:49 +0900 Subject: [PATCH 16/16] =?UTF-8?q?fix(enum)=20:=20enum=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/Diary/controller/DiariesController.java | 8 ++++---- src/main/java/org/sopt/Diary/entity/Category.java | 2 +- src/main/java/org/sopt/Diary/entity/SortType.java | 2 +- src/main/java/org/sopt/Diary/service/DiariesService.java | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/sopt/Diary/controller/DiariesController.java b/src/main/java/org/sopt/Diary/controller/DiariesController.java index b1060a5..9babc32 100644 --- a/src/main/java/org/sopt/Diary/controller/DiariesController.java +++ b/src/main/java/org/sopt/Diary/controller/DiariesController.java @@ -22,8 +22,8 @@ public DiariesController(DiariesService diariesService) { @GetMapping() public ResponseEntity getDiaries( @RequestHeader(name="userId" , required = false) Long userId, - @RequestParam(name = "category" , required = false, defaultValue = "all") final Category category, - @RequestParam(name = "sort",required = false, defaultValue = "latest") final SortType sortType) { + @RequestParam(name = "category" , required = false, defaultValue = "ALL") final Category category, + @RequestParam(name = "sort",required = false, defaultValue = "LATEST") final SortType sortType) { DiaryListRes diaryListRes = diariesService.getDiariesResponse( category,sortType, false, userId); return ResponseEntity.ok(diaryListRes); @@ -32,8 +32,8 @@ public ResponseEntity getDiaries( @GetMapping("/my") public ResponseEntity getMyDiaries( @Valid @RequestHeader("userId") long userId, - @Valid @RequestParam(name = "category",required = false, defaultValue = "all") final Category category, - @RequestParam(name = "sort",required = false, defaultValue = "latest")final SortType sortType) { + @Valid @RequestParam(name = "category",required = false, defaultValue = "ALL") final Category category, + @RequestParam(name = "sort",required = false, defaultValue = "LATEST")final SortType sortType) { DiaryListRes diaryListRes = diariesService.getDiariesResponse(category, sortType,true,userId); return ResponseEntity.ok(diaryListRes); diff --git a/src/main/java/org/sopt/Diary/entity/Category.java b/src/main/java/org/sopt/Diary/entity/Category.java index 9790bc4..7354e14 100644 --- a/src/main/java/org/sopt/Diary/entity/Category.java +++ b/src/main/java/org/sopt/Diary/entity/Category.java @@ -1,6 +1,6 @@ package org.sopt.Diary.entity; public enum Category { - food, school, movie, exercise, all + FOOD, SCHOOL, MOVIE, EXERCISE, ALL } diff --git a/src/main/java/org/sopt/Diary/entity/SortType.java b/src/main/java/org/sopt/Diary/entity/SortType.java index 13c2efd..1b2c68b 100644 --- a/src/main/java/org/sopt/Diary/entity/SortType.java +++ b/src/main/java/org/sopt/Diary/entity/SortType.java @@ -1,5 +1,5 @@ package org.sopt.Diary.entity; public enum SortType { - latest,quantity + LATEST,QUANTITY } diff --git a/src/main/java/org/sopt/Diary/service/DiariesService.java b/src/main/java/org/sopt/Diary/service/DiariesService.java index df50522..5350360 100644 --- a/src/main/java/org/sopt/Diary/service/DiariesService.java +++ b/src/main/java/org/sopt/Diary/service/DiariesService.java @@ -44,7 +44,7 @@ public DiaryListRes getDiariesResponse(Category category, SortType sortType, boo } // 선택된 카테고리에 따라 필터링 - if (category != Category.all) { + if (category != Category.ALL) { diaryEntities = diaryEntities.stream() .filter(diary -> diary.getCategory() == category) .collect(Collectors.toList()); @@ -62,8 +62,8 @@ public DiaryListRes getDiariesResponse(Category category, SortType sortType, boo private Comparator getComparator(SortType sortType) { return switch (sortType) { - case latest -> Comparator.comparing(DiaryEntity::getCreatedAt).reversed(); // 최신 순 정렬 - case quantity -> Comparator.comparingInt((DiaryEntity diary) -> diary.getContent().length()).reversed(); // 내용 길이 기준 내림차순 정렬 + case LATEST -> Comparator.comparing(DiaryEntity::getCreatedAt).reversed(); // 최신 순 정렬 + case QUANTITY -> Comparator.comparingInt((DiaryEntity diary) -> diary.getContent().length()).reversed(); // 내용 길이 기준 내림차순 정렬 }; }