From 1d571367a4602ffe1daf10d8a86ee72f77d5af86 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 20 Oct 2024 22:35:17 +0900 Subject: [PATCH 01/14] =?UTF-8?q?refactor:=20#13=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/domain/BirthDay.java | 35 +++++++++++++++++++ .../xcellentbe/domain/user/domain/User.java | 33 +++++------------ .../user/dto/UserProfileRequestDto.java | 2 -- .../user/dto/UserProfileResponseDto.java | 6 ++-- .../domain/user/dto/UserSignUpRequestDto.java | 3 -- 5 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java new file mode 100644 index 0000000..9dd3c58 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java @@ -0,0 +1,35 @@ +package com.leets.xcellentbe.domain.user.domain; + +import org.hibernate.grammars.hql.HqlParser; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@Embeddable +public class BirthDay { + + @NotNull + @Column(length=4) + private int year; + + @NotNull + @Column(length=2) + private int month; + + @NotNull + @Column(length=2) + private int day; + + @Builder + private BirthDay(int year, int month, int day) { + this.year = year; + this.month = month; + this.day = day; + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java index bf5669f..cd5c1df 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java @@ -10,6 +10,7 @@ import com.leets.xcellentbe.domain.user.Role; import jakarta.persistence.Column; +import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; @@ -80,48 +81,34 @@ public class User extends BaseTimeEntity { @Enumerated(EnumType.STRING) private Role userRole; - - @NotNull - @Column(length=4) - private int userBirthYear; - - @Column(length=2) - @NotNull - private int userBirthMonth; - - @Column(length=2) - @NotNull - private int userBirthDay; + @Embedded + private BirthDay userBirth; @Builder - private User(String customId, String email, String userName, String password, String phoneNumber, String description, int userBirthDay, int userBirthMonth, int userBirthYear, String socialEmail, Role userRole) { + private User(String customId, String email, String userName, String password, String phoneNumber, String description, BirthDay userBirth , Role userRole) { this.customId = customId; this.email = email; this.userName = userName; this.password = password; - this.phoneNumber= phoneNumber; + this.phoneNumber = phoneNumber; this.description = description; this.userStatus = UserStatus.ACTIVE; this.userRole = userRole; - this.userBirthMonth = userBirthMonth; - this.userBirthYear = userBirthYear; - this.userBirthDay = userBirthDay; + this.userBirth = userBirth; } public void passwordEncode(PasswordEncoder passwordEncoder) { //비밀번호 암호화 메소드 this.password = passwordEncoder.encode(this.password); } - public static User create(String customId, String email, String userName, String password, String phoneNumber, int userBirthMonth, int userBirthYear, int userBirthDay) { + public static User create(String customId, String email, String userName, String password, String phoneNumber, int userBirthYear, int userBirthDay, int userBirthMonth) { return User.builder() .customId(customId) .email(email) .userName(userName) .password(password) .phoneNumber(phoneNumber) - .userBirthDay(userBirthDay) - .userBirthYear(userBirthYear) - .userBirthMonth(userBirthMonth) + .userBirth(BirthDay.builder().day(userBirthDay).year(userBirthYear).month(userBirthMonth).build()) .userRole(Role.USER) .build(); } @@ -133,9 +120,7 @@ public void updateProfile(String userName, String phoneNumber, String customId, this.websiteUrl = websiteUrl; this.location = location; this.phoneNumber = phoneNumber; - this.userBirthYear = userBirthYear; - this.userBirthDay = userBirthDay; - this.userBirthMonth = userBirthMonth; + this.userBirth = userBirth; } public void updateProfileImage(String updateProfileImageUrl) { diff --git a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java index 536209a..51915b6 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java @@ -1,12 +1,10 @@ package com.leets.xcellentbe.domain.user.dto; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @NoArgsConstructor @Getter - public class UserProfileRequestDto { private String customId; private String userName; diff --git a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java index ca67739..e36f31d 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java @@ -51,9 +51,9 @@ public static UserProfileResponseDto from(User user) { .description(user.getDescription()) .websiteUrl(user.getWebsiteUrl()) .location(user.getLocation()) - .userBirthYear(user.getUserBirthYear()) - .userBirthMonth(user.getUserBirthMonth()) - .userBirthDay(user.getUserBirthDay()) + .userBirthYear(user.getUserBirth().getYear()) + .userBirthMonth(user.getUserBirth().getMonth()) + .userBirthDay(user.getUserBirth().getDay()) .build(); } } diff --git a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserSignUpRequestDto.java b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserSignUpRequestDto.java index 516afd1..decbe6c 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserSignUpRequestDto.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserSignUpRequestDto.java @@ -1,7 +1,5 @@ package com.leets.xcellentbe.domain.user.dto; -import java.time.LocalDate; - import lombok.Getter; import lombok.NoArgsConstructor; @@ -17,5 +15,4 @@ public class UserSignUpRequestDto { private int userBirthYear; private int userBirthMonth; private int userBirthDay; - } From 9a787149dc659fa57d5ae9036dd6231879192460 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 20 Oct 2024 23:15:50 +0900 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20#13=20=ED=8A=B9=EC=A0=95=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 쿼리스트링을 이용해 특정 사용자 프로필 조회 기능을 구현 --- .../user/controller/UserController.java | 36 ++++++++++++------- .../domain/user/service/UserService.java | 9 ++++- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java b/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java index 829c1f5..5e9bb47 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java @@ -35,32 +35,42 @@ public class UserController { private final UserService userService; - @GetMapping("/info") - @Operation(summary = "프로필 조회", description = "사용자의 프로필 내용을 조회합니다.") + @GetMapping("/myinfo") + @Operation(summary = "본인 프로필 조회", description = "본인의 프로필 내용을 조회합니다.") public ResponseEntity> getProfile(HttpServletRequest request) { return ResponseEntity.status(HttpStatus.OK) .body(GlobalResponseDto.success(userService.getProfile(request))); } - @PatchMapping("/info") - @Operation(summary = "프로필 수정", description = "사용자의 프로필을 수정합니다.") - public ResponseEntity> updateProfile(@RequestBody UserProfileRequestDto userProfileRequestDto, HttpServletRequest request) { - userService.updateProfile(request,userProfileRequestDto); + @PatchMapping("/myinfo") + @Operation(summary = "본인 프로필 수정", description = "본인의 프로필을 수정합니다.") + public ResponseEntity> updateProfile( + @RequestBody UserProfileRequestDto userProfileRequestDto, HttpServletRequest request) { + userService.updateProfile(request, userProfileRequestDto); return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success()); } + @GetMapping("/info") + @Operation(summary = "프로필 조회", description = "특정 사용자의 프로필 내용을 조회합니다.") + public ResponseEntity> getProfileWithoutToken(@RequestParam String customId) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(userService.getProfileWithoutToken(customId))); + } + @PatchMapping("/profile-image") @Operation(summary = "프로필 이미지 수정", description = "사용자의 프로필 이미지를 수정합니다.") - public ResponseEntity> updateProfileImage(@RequestParam("file") MultipartFile file, HttpServletRequest request) { - return ResponseEntity.status(HttpStatus.OK) - .body(GlobalResponseDto.success(userService.updateProfileImage(file, request))); + public ResponseEntity> updateProfileImage(@RequestParam("file") MultipartFile file, + HttpServletRequest request) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(userService.updateProfileImage(file, request))); } @PatchMapping("/background-image") @Operation(summary = "배경 이미지 수정", description = "사용자의 배경 이미지를 수정합니다.") - public ResponseEntity> updateBackgroundImage (@RequestParam("file") MultipartFile file, HttpServletRequest request){ - return ResponseEntity.status(HttpStatus.OK) - .body(GlobalResponseDto.success(userService.updateBackgroundProfileImage(file, request))); - } + public ResponseEntity> updateBackgroundImage(@RequestParam("file") MultipartFile file, + HttpServletRequest request) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(userService.updateBackgroundProfileImage(file, request))); } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java index 2d08c3e..a1a440b 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java @@ -52,12 +52,19 @@ public String register(UserSignUpRequestDto userSignUpRequestDto) { return "회원가입이 완료되었습니다."; } - // 사용자 정보 조회 메소드 + // 본인 정보 조회 메소드 public UserProfileResponseDto getProfile(HttpServletRequest request) { User user = getUser(request); return UserProfileResponseDto.from(user); } + // 특정 사용자 정보 조회 메소드 + public UserProfileResponseDto getProfileWithoutToken(String customId) + { + User user = userRepository.findByCustomId(customId).orElseThrow(UserNotFoundException::new); + return UserProfileResponseDto.from(user); + } + // 사용자 정보 수정 메소드 public void updateProfile(HttpServletRequest request, UserProfileRequestDto userProfileRequestDto) { From 6762df8ab1821a978d4b418ed81428755ef99b76 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 20 Oct 2024 23:22:59 +0900 Subject: [PATCH 03/14] =?UTF-8?q?refactor:=20#13=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/service/UserService.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java index a1a440b..5bbba35 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java @@ -2,24 +2,20 @@ import java.util.Optional; -import org.hibernate.engine.transaction.jta.platform.internal.SunOneJtaPlatform; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import com.leets.xcellentbe.domain.user.domain.User; -import com.leets.xcellentbe.domain.user.dto.UserProfileRequestDto; -import com.leets.xcellentbe.domain.user.exception.UserAlreadyExistsException; - import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import com.leets.xcellentbe.domain.user.dto.UserProfileRequestDto; +import com.leets.xcellentbe.domain.user.dto.UserProfileResponseDto; import com.leets.xcellentbe.domain.user.dto.UserSignUpRequestDto; - +import com.leets.xcellentbe.domain.user.exception.UserAlreadyExistsException; import com.leets.xcellentbe.domain.user.exception.UserNotFoundException; import com.leets.xcellentbe.global.auth.jwt.JwtService; import jakarta.servlet.http.HttpServletRequest; - -import com.leets.xcellentbe.domain.user.dto.UserProfileResponseDto; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; @@ -43,8 +39,11 @@ public String register(UserSignUpRequestDto userSignUpRequestDto) { throw new UserAlreadyExistsException(); } - User user = User.create(userSignUpRequestDto.getCustomId(), userSignUpRequestDto.getEmail(), userSignUpRequestDto.getUserName(), - userSignUpRequestDto.getPassword(), userSignUpRequestDto.getPhoneNumber(), userSignUpRequestDto.getUserBirthYear(), userSignUpRequestDto.getUserBirthDay(), userSignUpRequestDto.getUserBirthMonth()); + User user = User.create(userSignUpRequestDto.getCustomId(), userSignUpRequestDto.getEmail(), + userSignUpRequestDto.getUserName(), + userSignUpRequestDto.getPassword(), userSignUpRequestDto.getPhoneNumber(), + userSignUpRequestDto.getUserBirthYear(), userSignUpRequestDto.getUserBirthDay(), + userSignUpRequestDto.getUserBirthMonth()); user.passwordEncode(passwordEncoder); userRepository.save(user); @@ -59,17 +58,19 @@ public UserProfileResponseDto getProfile(HttpServletRequest request) { } // 특정 사용자 정보 조회 메소드 - public UserProfileResponseDto getProfileWithoutToken(String customId) - { + public UserProfileResponseDto getProfileWithoutToken(String customId) { User user = userRepository.findByCustomId(customId).orElseThrow(UserNotFoundException::new); return UserProfileResponseDto.from(user); } - // 사용자 정보 수정 메소드 public void updateProfile(HttpServletRequest request, UserProfileRequestDto userProfileRequestDto) { User user = getUser(request); - user.updateProfile(userProfileRequestDto.getUserName(), userProfileRequestDto.getPhoneNumber(), userProfileRequestDto.getCustomId(), userProfileRequestDto.getUserBirthYear(), userProfileRequestDto.getUserBirthDay(), userProfileRequestDto.getUserBirthMonth(), userProfileRequestDto.getDescription(), userProfileRequestDto.getWebsiteUrl(), userProfileRequestDto.getLocation()); + user.updateProfile(userProfileRequestDto.getUserName(), userProfileRequestDto.getPhoneNumber(), + userProfileRequestDto.getCustomId(), userProfileRequestDto.getUserBirthYear(), + userProfileRequestDto.getUserBirthDay(), userProfileRequestDto.getUserBirthMonth(), + userProfileRequestDto.getDescription(), userProfileRequestDto.getWebsiteUrl(), + userProfileRequestDto.getLocation()); } // 프로필 이미지 변경 메소드 From 1290c3ad81ba5164cfdd323d0af851337d4aefdd Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Mon, 21 Oct 2024 00:52:36 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20#13=20=ED=8C=94=EB=A1=9C=EC=9A=B0?= =?UTF-8?q?=20=EB=B0=8F=20=EC=96=B8=ED=8C=94=EB=A1=9C=EC=9A=B0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../follow/controller/FollowController.java | 42 +++++++++++++ .../domain/follow/domain/Follow.java | 16 +++++ .../domain/repository/FollowRepository.java | 4 ++ .../domain/follow/dto/FollowRequestDto.java | 8 +++ .../domain/follow/service/FollowService.java | 59 +++++++++++++++++++ .../domain/repository/UserRepository.java | 5 +- .../exception/GlobalExceptionHandler.java | 35 ++++++----- 7 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java create mode 100644 src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowRequestDto.java create mode 100644 src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java new file mode 100644 index 0000000..5972d6e --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java @@ -0,0 +1,42 @@ +package com.leets.xcellentbe.domain.follow.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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; + +import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; +import com.leets.xcellentbe.domain.follow.service.FollowService; +import com.leets.xcellentbe.global.response.GlobalResponseDto; + +import io.swagger.v3.oas.annotations.Operation; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api/profile") +@RequiredArgsConstructor +public class FollowController { + private final FollowService followService; + + @PostMapping("/follow") + @Operation(summary = "팔로우", description = "다른 사용자를 팔로우합니다.") + public ResponseEntity> followUser(@RequestBody FollowRequestDto requestDto, + HttpServletRequest request) { + followService.followUser(requestDto, request); + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success()); + } + + @DeleteMapping("/follow") + @Operation(summary = "언팔로우", description = "다른 사용자를 언팔로우합니다.") + public ResponseEntity> unfollowerUser(@RequestBody FollowRequestDto requestDto, + HttpServletRequest request) { + followService.unfollowUser(requestDto, request); + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success()); + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java b/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java index f325b5e..7b09b93 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java @@ -11,6 +11,7 @@ import jakarta.persistence.ManyToOne; import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -32,4 +33,19 @@ public class Follow { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "follower_id") private User follower; + + @Builder + private Follow(User following, User follower) { + this.following = following; + this.follower = follower; + } + + public static Follow create(User follower, User following) { + return Follow.builder() + .follower(follower) + .following(following) + .build(); + } } + + diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java b/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java index 45920fe..35b65b2 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java @@ -1,8 +1,12 @@ package com.leets.xcellentbe.domain.follow.domain.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import com.leets.xcellentbe.domain.follow.domain.Follow; +import com.leets.xcellentbe.domain.user.domain.User; public interface FollowRepository extends JpaRepository { + Optional findByFollowerAndFollowing(User user, User targetUser); } diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowRequestDto.java b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowRequestDto.java new file mode 100644 index 0000000..7d3aa24 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowRequestDto.java @@ -0,0 +1,8 @@ +package com.leets.xcellentbe.domain.follow.dto; + +import lombok.Getter; + +@Getter +public class FollowRequestDto { + private String customId; +} diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java new file mode 100644 index 0000000..e2fc163 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -0,0 +1,59 @@ +package com.leets.xcellentbe.domain.follow.service; + +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import com.leets.xcellentbe.domain.follow.domain.Follow; +import com.leets.xcellentbe.domain.follow.domain.repository.FollowRepository; +import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; +import com.leets.xcellentbe.domain.user.domain.User; +import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import com.leets.xcellentbe.domain.user.exception.UserNotFoundException; +import com.leets.xcellentbe.global.auth.jwt.JwtService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.transaction.Transactional; +import lombok.AllArgsConstructor; + +@Service +@Transactional +@AllArgsConstructor +public class FollowService { + + private final UserRepository userRepository; + private final JwtService jwtService; + private final FollowRepository followRepository; + + public void followUser(FollowRequestDto requestDto, HttpServletRequest request) { + User user = getUser(request); + User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) + .orElseThrow(UserNotFoundException::new); + + Follow follow = Follow.create(user, targetUser); + followRepository.save(follow); + } + + public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request) { + User user = getUser(request); + User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) + .orElseThrow(UserNotFoundException::new); + + Optional follow = followRepository.findByFollowerAndFollowing(user, targetUser); + followRepository.delete(follow.get()); // TODO: Optional.get() is dangerous + } + + //JWT 토큰 해독하여 사용자 정보 반환 메소드 + private User getUser(HttpServletRequest request) { + Optional user = jwtService.extractAccessToken(request) + .filter(jwtService::isTokenValid) + .flatMap(accessToken -> jwtService.extractEmail(accessToken)) + .flatMap(userRepository::findByEmail); + + if (user.isEmpty()) { + throw new UserNotFoundException(); + } + + return user.get(); + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java index ed4938f..85db6fc 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java @@ -8,7 +8,8 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); - Optional findByCustomId(String customId);; - Optional findByRefreshToken(String refreshToken); + Optional findByCustomId(String customId); + + Optional findByRefreshToken(String refreshToken); } diff --git a/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java b/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java index bc2e940..48a5493 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java @@ -1,36 +1,39 @@ package com.leets.xcellentbe.global.error.exception; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; -import com.leets.xcellentbe.global.error.*; + +import com.leets.xcellentbe.global.error.ErrorCode; +import com.leets.xcellentbe.global.error.ErrorResponse; import com.leets.xcellentbe.global.response.GlobalResponseDto; +import lombok.extern.slf4j.Slf4j; + @Slf4j @ControllerAdvice public class GlobalExceptionHandler { + private static void showErrorLog(ErrorCode errorCode) { + log.error("errorCode: {}, message: {}", errorCode.getCode(), errorCode.getMessage()); + } + + // @ExceptionHandler(Exception.class) + // public ResponseEntity handleGenericException(Exception ex) { + // ErrorCode errorCode = ErrorCode.INTERNAL_SERVER_ERROR; + // ErrorResponse errorResponse = new ErrorResponse(errorCode); + // showErrorLog(errorCode); + // return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())).body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); + // } + @ExceptionHandler(CommonException.class) // Custom Exception을 포괄적으로 처리 public ResponseEntity> handleCommonException(CommonException ex) { ErrorCode errorCode = ex.getErrorCode(); // 전달된 예외에서 에러 코드 가져오기 ErrorResponse errorResponse = new ErrorResponse(errorCode); showErrorLog(errorCode); - return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())).body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); - } - - @ExceptionHandler(Exception.class) - public ResponseEntity handleGenericException(Exception ex) { - ErrorCode errorCode = ErrorCode.INTERNAL_SERVER_ERROR; - ErrorResponse errorResponse = new ErrorResponse(errorCode); - showErrorLog(errorCode); - return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())).body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); - } - - - private static void showErrorLog(ErrorCode errorCode) { - log.error("errorCode: {}, message: {}", errorCode.getCode(), errorCode.getMessage()); + return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())) + .body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); } } From c2283aa8652167ef3546ccf84994b22a4eda973b Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Mon, 21 Oct 2024 19:00:50 +0900 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20#13=20=ED=8C=94=EB=A1=9C=EC=9A=B0?= =?UTF-8?q?=20=EB=B0=8F=20=EC=96=B8=ED=8C=94=EB=A1=9C=EC=9A=B0=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../follow/exception/FollowOperationError.java | 10 ++++++++++ .../domain/follow/service/FollowService.java | 13 +++++++++++-- .../leets/xcellentbe/global/error/ErrorCode.java | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/domain/follow/exception/FollowOperationError.java diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/exception/FollowOperationError.java b/src/main/java/com/leets/xcellentbe/domain/follow/exception/FollowOperationError.java new file mode 100644 index 0000000..9b90473 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/follow/exception/FollowOperationError.java @@ -0,0 +1,10 @@ +package com.leets.xcellentbe.domain.follow.exception; + +import com.leets.xcellentbe.global.error.ErrorCode; +import com.leets.xcellentbe.global.error.exception.CommonException; + +public class FollowOperationError extends CommonException { + public FollowOperationError() { + super(ErrorCode.FOLLOW_OPERATION_ERROR); + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java index e2fc163..9c08535 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -7,6 +7,7 @@ import com.leets.xcellentbe.domain.follow.domain.Follow; import com.leets.xcellentbe.domain.follow.domain.repository.FollowRepository; import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; +import com.leets.xcellentbe.domain.follow.exception.FollowOperationError; import com.leets.xcellentbe.domain.user.domain.User; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; import com.leets.xcellentbe.domain.user.exception.UserNotFoundException; @@ -30,6 +31,12 @@ public void followUser(FollowRequestDto requestDto, HttpServletRequest request) User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) .orElseThrow(UserNotFoundException::new); + boolean isFollowing = followRepository.findByFollowerAndFollowing(user, targetUser).isPresent(); + + if (isFollowing) { + throw new FollowOperationError(); + } + Follow follow = Follow.create(user, targetUser); followRepository.save(follow); } @@ -39,8 +46,10 @@ public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) .orElseThrow(UserNotFoundException::new); - Optional follow = followRepository.findByFollowerAndFollowing(user, targetUser); - followRepository.delete(follow.get()); // TODO: Optional.get() is dangerous + Follow follow = followRepository.findByFollowerAndFollowing(user, targetUser) + .orElseThrow(FollowOperationError::new); + + followRepository.delete(follow); } //JWT 토큰 해독하여 사용자 정보 반환 메소드 diff --git a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java index 1b023d3..6ce72fd 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java +++ b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java @@ -14,6 +14,7 @@ public enum ErrorCode { CHAT_ROOM_FORBIDDEN(403, "CHAT_ROOM_FORBIDDEN","권한이 없는 채팅방입니다."), USER_NOT_FOUND(404, "USER_NOT_FOUND", "유저를 찾을 수 없습니다."), EXPIRED_TOKEN(403, "EXPIRED_TOKEN", "만료된 토큰입니다."), + FOLLOW_OPERATION_ERROR(409, "FOLLOW_OPERATION_ERROR", "적절하지 않은 팔로우 요청입니다."), USER_ALREADY_EXISTS(412 , "ALREADY_EXISTS_EXCEPTION" , "이미 존재하는 사용자입니다." ), ARTICLE_NOT_FOUND(404, "ARTICLE_NOT_FOUND", "게시물을 찾을 수 없습니다."), CHAT_ROOM_NOT_FOUND(404, "CHAT_ROOM_NOT_FOUND", "채팅방을 찾을 수 없습니다."), From 7aa2eb312b91fe1ee763a49c3bd291b938253345 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Mon, 21 Oct 2024 23:30:24 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat:=20#13=20=ED=8C=94=EB=A1=9C=EC=9B=8C?= =?UTF-8?q?=20=EB=B0=8F=20=ED=8C=94=EB=A1=9C=EC=9E=89=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../follow/controller/FollowController.java | 20 ++++++++++++ .../domain/repository/FollowRepository.java | 5 +++ .../dto/FollowerAndFollowingResponseDto.java | 31 +++++++++++++++++++ .../domain/follow/service/FollowService.java | 29 +++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java index 5972d6e..a23efa2 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java @@ -1,14 +1,20 @@ package com.leets.xcellentbe.domain.follow.controller; +import java.util.List; + +import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; +import com.leets.xcellentbe.domain.follow.dto.FollowerAndFollowingResponseDto; import com.leets.xcellentbe.domain.follow.service.FollowService; import com.leets.xcellentbe.global.response.GlobalResponseDto; @@ -39,4 +45,18 @@ public ResponseEntity> unfollowerUser(@Reque return ResponseEntity.status(HttpStatus.OK) .body(GlobalResponseDto.success()); } + + @GetMapping("/following") + @Operation(summary = "팔로잉 조회", description = "사용자가 팔로우하는 사용자 목록을 조회합니다.") + public ResponseEntity>> getFollowingList(@RequestParam(required = false, defaultValue = "0") int pageNo, @RequestParam String customId) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(followService.getFollowingList(customId, pageNo))); + } + + @GetMapping("/follower") + @Operation(summary = "팔로워 조회", description = "사용자를 팔로우하는 사용자 목록을 조회합니다.") + public ResponseEntity>> getFollowerList(@RequestParam(required = false, defaultValue = "0") int pageNo, @RequestParam String customId) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(followService.getFollowerList(customId, pageNo))); + } } diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java b/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java index 35b65b2..39011cb 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java @@ -1,7 +1,10 @@ package com.leets.xcellentbe.domain.follow.domain.repository; +import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import com.leets.xcellentbe.domain.follow.domain.Follow; @@ -9,4 +12,6 @@ public interface FollowRepository extends JpaRepository { Optional findByFollowerAndFollowing(User user, User targetUser); + Page findByFollower(User user, Pageable pageable); + Page findByFollowing(User user, Pageable pageable); } diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java new file mode 100644 index 0000000..4c0349f --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java @@ -0,0 +1,31 @@ +package com.leets.xcellentbe.domain.follow.dto; + +import java.util.List; + +import com.leets.xcellentbe.domain.follow.domain.Follow; +import com.leets.xcellentbe.domain.user.domain.User; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class FollowerAndFollowingResponseDto { + private String customId; + private String userName; + + + @Builder + public FollowerAndFollowingResponseDto(String customId, String userName) { + this.customId = customId; + this.userName = userName; + } + + public static FollowerAndFollowingResponseDto from(Follow follow) { + User user = follow.getFollowing(); + return FollowerAndFollowingResponseDto.builder() + .customId(user.getCustomId()) + .userName(user.getUserName()) + .build(); + } + +} diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java index 9c08535..851d1d3 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -1,12 +1,18 @@ package com.leets.xcellentbe.domain.follow.service; +import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import com.leets.xcellentbe.domain.follow.domain.Follow; import com.leets.xcellentbe.domain.follow.domain.repository.FollowRepository; import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; +import com.leets.xcellentbe.domain.follow.dto.FollowerAndFollowingResponseDto; import com.leets.xcellentbe.domain.follow.exception.FollowOperationError; import com.leets.xcellentbe.domain.user.domain.User; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; @@ -22,6 +28,7 @@ @AllArgsConstructor public class FollowService { + private static final int PAGE_SIZE = 10; private final UserRepository userRepository; private final JwtService jwtService; private final FollowRepository followRepository; @@ -52,6 +59,28 @@ public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request followRepository.delete(follow); } + public Page getFollowingList(String customId, int pageNo) { + Pageable pageable = PageRequest.of(pageNo, PAGE_SIZE, Sort.by(Sort.Direction.DESC, "following")); + + User user = userRepository.findByCustomId(customId) + .orElseThrow(UserNotFoundException::new); + + Page page = followRepository.findByFollower(user, pageable).map(FollowerAndFollowingResponseDto::from); + + return page; + + } + public Page getFollowerList(String customId, int pageNo) { + Pageable pageable = PageRequest.of(pageNo, PAGE_SIZE, Sort.by(Sort.Direction.DESC, "following")); + + User user = userRepository.findByCustomId(customId) + .orElseThrow(UserNotFoundException::new); + + Page page = followRepository.findByFollowing(user, pageable).map(FollowerAndFollowingResponseDto::from); + + return page; + } + //JWT 토큰 해독하여 사용자 정보 반환 메소드 private User getUser(HttpServletRequest request) { Optional user = jwtService.extractAccessToken(request) From 1032a6b301d620c8e0b31e27677ded1bf04ae771 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Mon, 21 Oct 2024 23:40:50 +0900 Subject: [PATCH 07/14] =?UTF-8?q?refactor:=20#13=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcellentbe/XcellentBeApplication.java | 6 +- .../follow/controller/FollowController.java | 12 +-- .../domain/repository/FollowRepository.java | 3 +- .../dto/FollowerAndFollowingResponseDto.java | 3 - .../domain/follow/service/FollowService.java | 34 ++++--- .../user/controller/UserController.java | 13 +-- .../domain/user/domain/BirthDay.java | 8 +- .../xcellentbe/domain/user/domain/User.java | 19 ++-- .../exception/UserAlreadyExistsException.java | 6 +- .../domain/user/service/S3UploadService.java | 10 +- .../global/auth/email/EmailCannotBeSent.java | 6 +- .../global/auth/email/EmailService.java | 51 +++++----- .../global/auth/email/RedisService.java | 28 +++--- .../auth/jwt/JwtAuthenticationFilter.java | 16 ++-- .../global/auth/jwt/JwtService.java | 41 ++++---- .../global/auth/login/AuthController.java | 6 +- .../login/CustomJsonAuthenticationFilter.java | 22 +++-- .../global/auth/login/LoginService.java | 11 ++- .../login/handler/LoginFailureHandler.java | 16 ++-- .../login/handler/LoginSuccessHandler.java | 14 ++- .../auth/login/oauth/CustomOAuthUser.java | 5 +- .../login/oauth/CustomOAuthUserService.java | 11 ++- .../auth/login/oauth/GoogleOAuthUserInfo.java | 3 +- .../auth/login/oauth/OAuthAttributes.java | 10 +- .../login/oauth/OAuthLoginSuccessHandler.java | 93 ++++++++++--------- .../global/auth/login/oauth/PasswordUtil.java | 17 ++-- .../xcellentbe/global/config/AwsConfig.java | 9 +- .../global/config/SecurityConfig.java | 21 ++--- .../global/config/swagger/SwaggerConfig.java | 34 +++---- .../xcellentbe/global/error/ErrorCode.java | 7 +- .../global/error/ErrorResponse.java | 1 + .../global/response/GlobalResponseDto.java | 17 ++-- 32 files changed, 281 insertions(+), 272 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/XcellentBeApplication.java b/src/main/java/com/leets/xcellentbe/XcellentBeApplication.java index 7e6cabc..64f49fe 100644 --- a/src/main/java/com/leets/xcellentbe/XcellentBeApplication.java +++ b/src/main/java/com/leets/xcellentbe/XcellentBeApplication.java @@ -8,8 +8,8 @@ @EnableJpaAuditing public class XcellentBeApplication { - public static void main(String[] args) { - SpringApplication.run(XcellentBeApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(XcellentBeApplication.class, args); + } } diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java index a23efa2..d7b2af3 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java @@ -1,7 +1,5 @@ package com.leets.xcellentbe.domain.follow.controller; -import java.util.List; - import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -48,15 +46,17 @@ public ResponseEntity> unfollowerUser(@Reque @GetMapping("/following") @Operation(summary = "팔로잉 조회", description = "사용자가 팔로우하는 사용자 목록을 조회합니다.") - public ResponseEntity>> getFollowingList(@RequestParam(required = false, defaultValue = "0") int pageNo, @RequestParam String customId) { + public ResponseEntity>> getFollowingList( + @RequestParam(required = false, defaultValue = "1") int pageNo, @RequestParam String customId) { return ResponseEntity.status(HttpStatus.OK) - .body(GlobalResponseDto.success(followService.getFollowingList(customId, pageNo))); + .body(GlobalResponseDto.success(followService.getFollowingList(customId, pageNo - 1))); } @GetMapping("/follower") @Operation(summary = "팔로워 조회", description = "사용자를 팔로우하는 사용자 목록을 조회합니다.") - public ResponseEntity>> getFollowerList(@RequestParam(required = false, defaultValue = "0") int pageNo, @RequestParam String customId) { + public ResponseEntity>> getFollowerList( + @RequestParam(required = false, defaultValue = "1") int pageNo, @RequestParam String customId) { return ResponseEntity.status(HttpStatus.OK) - .body(GlobalResponseDto.success(followService.getFollowerList(customId, pageNo))); + .body(GlobalResponseDto.success(followService.getFollowerList(customId, pageNo - 1))); } } diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java b/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java index 39011cb..be8b621 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/domain/repository/FollowRepository.java @@ -1,6 +1,5 @@ package com.leets.xcellentbe.domain.follow.domain.repository; -import java.util.List; import java.util.Optional; import org.springframework.data.domain.Page; @@ -12,6 +11,8 @@ public interface FollowRepository extends JpaRepository { Optional findByFollowerAndFollowing(User user, User targetUser); + Page findByFollower(User user, Pageable pageable); + Page findByFollowing(User user, Pageable pageable); } diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java index 4c0349f..da6f18c 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java @@ -1,7 +1,5 @@ package com.leets.xcellentbe.domain.follow.dto; -import java.util.List; - import com.leets.xcellentbe.domain.follow.domain.Follow; import com.leets.xcellentbe.domain.user.domain.User; @@ -13,7 +11,6 @@ public class FollowerAndFollowingResponseDto { private String customId; private String userName; - @Builder public FollowerAndFollowingResponseDto(String customId, String userName) { this.customId = customId; diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java index 851d1d3..3184076 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -1,6 +1,5 @@ package com.leets.xcellentbe.domain.follow.service; -import java.util.List; import java.util.Optional; import org.springframework.data.domain.Page; @@ -33,6 +32,7 @@ public class FollowService { private final JwtService jwtService; private final FollowRepository followRepository; + // 팔로우 public void followUser(FollowRequestDto requestDto, HttpServletRequest request) { User user = getUser(request); User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) @@ -48,6 +48,7 @@ public void followUser(FollowRequestDto requestDto, HttpServletRequest request) followRepository.save(follow); } + // 언팔로우 public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request) { User user = getUser(request); User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) @@ -59,26 +60,33 @@ public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request followRepository.delete(follow); } + // 팔로잉 목록 조회 public Page getFollowingList(String customId, int pageNo) { - Pageable pageable = PageRequest.of(pageNo, PAGE_SIZE, Sort.by(Sort.Direction.DESC, "following")); + User user = findUserByCustomId(customId); + Pageable pageable = createPageable(pageNo); - User user = userRepository.findByCustomId(customId) - .orElseThrow(UserNotFoundException::new); - - Page page = followRepository.findByFollower(user, pageable).map(FollowerAndFollowingResponseDto::from); + return followRepository.findByFollower(user, pageable) + .map(FollowerAndFollowingResponseDto::from); + } - return page; + // 팔로워 목록 조회 + public Page getFollowerList(String customId, int pageNo) { + User user = findUserByCustomId(customId); + Pageable pageable = createPageable(pageNo); + return followRepository.findByFollowing(user, pageable) + .map(FollowerAndFollowingResponseDto::from); } - public Page getFollowerList(String customId, int pageNo) { - Pageable pageable = PageRequest.of(pageNo, PAGE_SIZE, Sort.by(Sort.Direction.DESC, "following")); - User user = userRepository.findByCustomId(customId) + // 커스텀아이디로 유저 검색 + private User findUserByCustomId(String customId) { + return userRepository.findByCustomId(customId) .orElseThrow(UserNotFoundException::new); + } - Page page = followRepository.findByFollowing(user, pageable).map(FollowerAndFollowingResponseDto::from); - - return page; + // 페이지네이션 객체 생성 + private Pageable createPageable(int pageNo) { + return PageRequest.of(pageNo, PAGE_SIZE, Sort.by(Sort.Direction.DESC, "following")); } //JWT 토큰 해독하여 사용자 정보 반환 메소드 diff --git a/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java b/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java index 5e9bb47..2df4df0 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java @@ -1,28 +1,18 @@ package com.leets.xcellentbe.domain.user.controller; -import java.io.IOException; - import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; 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.multipart.MultipartFile; -import com.leets.xcellentbe.domain.user.domain.User; -import com.leets.xcellentbe.domain.user.dto.UserLoginRequestDto; import com.leets.xcellentbe.domain.user.dto.UserProfileRequestDto; import com.leets.xcellentbe.domain.user.dto.UserProfileResponseDto; -import com.leets.xcellentbe.domain.user.dto.UserSignUpRequestDto; -import com.leets.xcellentbe.domain.user.service.S3UploadService; import com.leets.xcellentbe.domain.user.service.UserService; -import com.leets.xcellentbe.global.auth.email.EmailRequestDto; import com.leets.xcellentbe.global.response.GlobalResponseDto; import io.swagger.v3.oas.annotations.Operation; @@ -52,7 +42,8 @@ public ResponseEntity> updateProfile( @GetMapping("/info") @Operation(summary = "프로필 조회", description = "특정 사용자의 프로필 내용을 조회합니다.") - public ResponseEntity> getProfileWithoutToken(@RequestParam String customId) { + public ResponseEntity> getProfileWithoutToken( + @RequestParam String customId) { return ResponseEntity.status(HttpStatus.OK) .body(GlobalResponseDto.success(userService.getProfileWithoutToken(customId))); } diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java index 9dd3c58..45ab3dc 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/BirthDay.java @@ -1,7 +1,5 @@ package com.leets.xcellentbe.domain.user.domain; -import org.hibernate.grammars.hql.HqlParser; - import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.validation.constraints.NotNull; @@ -15,15 +13,15 @@ public class BirthDay { @NotNull - @Column(length=4) + @Column(length = 4) private int year; @NotNull - @Column(length=2) + @Column(length = 2) private int month; @NotNull - @Column(length=2) + @Column(length = 2) private int day; @Builder diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java index cd5c1df..dc80407 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java @@ -1,7 +1,6 @@ package com.leets.xcellentbe.domain.user.domain; import java.time.LocalDateTime; -import java.time.LocalDate; import org.springframework.security.crypto.password.PasswordEncoder; @@ -19,7 +18,6 @@ import jakarta.persistence.Id; import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -85,7 +83,8 @@ public class User extends BaseTimeEntity { private BirthDay userBirth; @Builder - private User(String customId, String email, String userName, String password, String phoneNumber, String description, BirthDay userBirth , Role userRole) { + private User(String customId, String email, String userName, String password, String phoneNumber, + String description, BirthDay userBirth, Role userRole) { this.customId = customId; this.email = email; this.userName = userName; @@ -97,11 +96,8 @@ private User(String customId, String email, String userName, String password, St this.userBirth = userBirth; } - public void passwordEncode(PasswordEncoder passwordEncoder) { //비밀번호 암호화 메소드 - this.password = passwordEncoder.encode(this.password); - } - - public static User create(String customId, String email, String userName, String password, String phoneNumber, int userBirthYear, int userBirthDay, int userBirthMonth) { + public static User create(String customId, String email, String userName, String password, String phoneNumber, + int userBirthYear, int userBirthDay, int userBirthMonth) { return User.builder() .customId(customId) .email(email) @@ -113,7 +109,12 @@ public static User create(String customId, String email, String userName, String .build(); } - public void updateProfile(String userName, String phoneNumber, String customId, int userBirthYear, int userBirthDay, int userBirthMonth, String description, String websiteUrl, String location) { + public void passwordEncode(PasswordEncoder passwordEncoder) { //비밀번호 암호화 메소드 + this.password = passwordEncoder.encode(this.password); + } + + public void updateProfile(String userName, String phoneNumber, String customId, int userBirthYear, int userBirthDay, + int userBirthMonth, String description, String websiteUrl, String location) { this.userName = userName; this.customId = customId; this.description = description; diff --git a/src/main/java/com/leets/xcellentbe/domain/user/exception/UserAlreadyExistsException.java b/src/main/java/com/leets/xcellentbe/domain/user/exception/UserAlreadyExistsException.java index d67551c..1bfc1a7 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/exception/UserAlreadyExistsException.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/exception/UserAlreadyExistsException.java @@ -4,7 +4,7 @@ import com.leets.xcellentbe.global.error.exception.CommonException; public class UserAlreadyExistsException extends CommonException { - public UserAlreadyExistsException() { - super(ErrorCode.USER_ALREADY_EXISTS); - } + public UserAlreadyExistsException() { + super(ErrorCode.USER_ALREADY_EXISTS); + } } diff --git a/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java b/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java index 66c38c9..91af467 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java @@ -38,7 +38,7 @@ public String upload(MultipartFile multipartFile, String dirName) { // dirName File uploadFile = convert(multipartFile). orElseThrow(() -> new RuntimeException()); return upload(uploadFile, dirName); - } catch(IOException e) { + } catch (IOException e) { throw new InternalServerErrorException(); } @@ -56,22 +56,22 @@ private String upload(File uploadFile, String dirName) { private String putS3(File uploadFile, String fileName) { amazonS3Client.putObject( new PutObjectRequest(bucket, fileName, uploadFile) - .withCannedAcl(CannedAccessControlList.PublicRead) // PublicRead 권한으로 업로드 됨 + .withCannedAcl(CannedAccessControlList.PublicRead) // PublicRead 권한으로 업로드 됨 ); return amazonS3Client.getUrl(bucket, fileName).toString(); } private void removeNewFile(File targetFile) { - if(targetFile.delete()) { + if (targetFile.delete()) { log.info("파일이 삭제되었습니다."); - }else { + } else { log.info("파일이 삭제되지 못했습니다."); } } private Optional convert(MultipartFile file) throws IOException { File convertFile = new File(file.getOriginalFilename()); // 업로드한 파일의 이름 - if(convertFile.createNewFile()) { + if (convertFile.createNewFile()) { try (FileOutputStream fos = new FileOutputStream(convertFile)) { fos.write(file.getBytes()); } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java index 5cd6ce9..a042dbe 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java @@ -3,10 +3,8 @@ import com.leets.xcellentbe.global.error.ErrorCode; import com.leets.xcellentbe.global.error.exception.CommonException; -public class EmailCannotBeSent extends CommonException -{ - public EmailCannotBeSent() - { +public class EmailCannotBeSent extends CommonException { + public EmailCannotBeSent() { super(ErrorCode.EMAIL_CANNOT_BE_SENT); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index f4f45b5..aa37272 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -1,16 +1,17 @@ package com.leets.xcellentbe.global.auth.email; +import java.util.Random; + +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; -import jakarta.mail.MessagingException; + +import com.leets.xcellentbe.global.error.exception.custom.InvalidInputValueException; + import jakarta.mail.internet.MimeMessage; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.mail.javamail.MimeMessageHelper; -import java.util.Random; - -import com.leets.xcellentbe.global.error.exception.custom.InvalidInputValueException; @Transactional @RequiredArgsConstructor @@ -27,14 +28,13 @@ public void makeRandomNumber() { this.authNumber = 100000 + r.nextInt(900000); } - //mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성합니다. - public String joinEmail(String email) { + public String joinEmail(String email) { makeRandomNumber(); String toMail = email; String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목 String content = - "인증 번호는 " + authNumber + "입니다." + + "인증 번호는 " + authNumber + "입니다." + "
" + "인증번호를 제대로 입력해주세요"; //이메일 내용 삽입 mailSend(toMail, title, content); @@ -44,23 +44,22 @@ public String joinEmail(String email) { //이메일을 전송합니다. public void mailSend(String toMail, String title, String content) { - if(redisService.getData(toMail)!=null){ + if (redisService.getData(toMail) != null) { throw new AuthCodeAlreadySentException(); } - try { - MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 - MimeMessageHelper helper = new MimeMessageHelper(message, true, - "utf-8");// true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 - helper.setTo(toMail);//이메일의 수신자 주소 설정 - helper.setSubject(title);//이메일의 제목을 설정 - helper.setText(content, true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. - mailSender.send(message); - } - catch(Exception e) { - throw new EmailCannotBeSent(); - } - redisService.setDataExpire(toMail,Integer.toString(authNumber)); + try { + MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 + MimeMessageHelper helper = new MimeMessageHelper(message, true, + "utf-8");// true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 + helper.setTo(toMail);//이메일의 수신자 주소 설정 + helper.setSubject(title);//이메일의 제목을 설정 + helper.setText(content, true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. + mailSender.send(message); + } catch (Exception e) { + throw new EmailCannotBeSent(); + } + redisService.setDataExpire(toMail, Integer.toString(authNumber)); } public String checkAuthNum(String email, String authNum) { @@ -68,11 +67,9 @@ public String checkAuthNum(String email, String authNum) { if (storedAuthNum == null) { return "인증번호가 만료되었습니다."; - } - else if(!storedAuthNum.equals(authNum)){ + } else if (!storedAuthNum.equals(authNum)) { throw new InvalidInputValueException(); - } - else { + } else { return "인증에 성공하였습니다."; } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java index 8be9cd5..7f62305 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java @@ -2,11 +2,12 @@ import java.time.Duration; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import org.springframework.data.redis.core.ValueOperations; -import org.springframework.data.redis.core.StringRedisTemplate; + @Service @RequiredArgsConstructor public class RedisService { @@ -14,20 +15,23 @@ public class RedisService { private final StringRedisTemplate redisTemplate;//Redis에 접근하기 위한 Spring의 Redis 템플릿 클래스 - public String getData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 가져오는 메서드 - ValueOperations valueOperations=redisTemplate.opsForValue(); + public String getData(String key) {//지정된 키(key)에 해당하는 데이터를 Redis에서 가져오는 메서드 + ValueOperations valueOperations = redisTemplate.opsForValue(); return valueOperations.get(key); } - public void setData(String key,String value){//지정된 키(key)에 값을 저장하는 메서드 - ValueOperations valueOperations=redisTemplate.opsForValue(); - valueOperations.set(key,value); + + public void setData(String key, String value) {//지정된 키(key)에 값을 저장하는 메서드 + ValueOperations valueOperations = redisTemplate.opsForValue(); + valueOperations.set(key, value); } - public void setDataExpire(String key,String value){//지정된 키(key)에 값을 저장하고, 지정된 시간(duration) 후에 데이터가 만료되도록 설정하는 메서드 - ValueOperations valueOperations=redisTemplate.opsForValue(); - Duration expireDuration=Duration.ofSeconds(AUTH_CODE_EXPIRE_SECONDS); - valueOperations.set(key,value,expireDuration); + + public void setDataExpire(String key, String value) {//지정된 키(key)에 값을 저장하고, 지정된 시간(duration) 후에 데이터가 만료되도록 설정하는 메서드 + ValueOperations valueOperations = redisTemplate.opsForValue(); + Duration expireDuration = Duration.ofSeconds(AUTH_CODE_EXPIRE_SECONDS); + valueOperations.set(key, value, expireDuration); } - public void deleteData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 삭제하는 메서드 + + public void deleteData(String key) {//지정된 키(key)에 해당하는 데이터를 Redis에서 삭제하는 메서드 redisTemplate.delete(key); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java index b474a43..6a8fb1d 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java @@ -1,7 +1,7 @@ package com.leets.xcellentbe.global.auth.jwt; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import java.io.IOException; + import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; @@ -10,14 +10,15 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.filter.OncePerRequestFilter; +import com.leets.xcellentbe.domain.user.domain.User; +import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; + import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; - -import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; -import com.leets.xcellentbe.domain.user.domain.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; /** * Jwt 인증 필터 @@ -44,7 +45,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { if (request.getRequestURI().equals(NO_CHECK_URL)) { filterChain.doFilter(request, response); // "/login" 요청이 들어오면, 다음 필터 호출 return; // return으로 이후 현재 필터 진행 막기 (안해주면 아래로 내려가서 계속 필터 진행시킴) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java index 28132cb..328ec21 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java @@ -1,19 +1,22 @@ -package com.leets.xcellentbe.global.auth.jwt;; +package com.leets.xcellentbe.global.auth.jwt; + +import java.util.Date; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.util.Date; -import java.util.Optional; +; @Service @RequiredArgsConstructor @@ -21,32 +24,26 @@ @Slf4j public class JwtService { + /** + * JWT의 Subject와 Claim으로 email 사용 -> 클레임의 name을 "email"으로 설정 + * JWT의 헤더에 들어오는 값 : 'Authorization(Key) = Bearer {토큰} (Value)' 형식 + */ + private static final String ACCESS_TOKEN_SUBJECT = "AccessToken"; + private static final String REFRESH_TOKEN_SUBJECT = "RefreshToken"; + private static final String EMAIL_CLAIM = "email"; + private static final String BEARER = "Bearer "; + private final UserRepository userRepository; @Value("${jwt.secretKey}") private String secretKey; - @Value("${jwt.access.expiration}") private Long accessTokenExpirationPeriod; - @Value("${jwt.refresh.expiration}") private Long refreshTokenExpirationPeriod; - @Value("${jwt.access.header}") private String accessHeader; - @Value("${jwt.refresh.header}") private String refreshHeader; - /** - * JWT의 Subject와 Claim으로 email 사용 -> 클레임의 name을 "email"으로 설정 - * JWT의 헤더에 들어오는 값 : 'Authorization(Key) = Bearer {토큰} (Value)' 형식 - */ - private static final String ACCESS_TOKEN_SUBJECT = "AccessToken"; - private static final String REFRESH_TOKEN_SUBJECT = "RefreshToken"; - private static final String EMAIL_CLAIM = "email"; - private static final String BEARER = "Bearer "; - - private final UserRepository userRepository; - /** * AccessToken 생성 메소드 */ diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index ec75fef..6541bd2 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -13,11 +13,9 @@ import com.leets.xcellentbe.global.auth.email.EmailCheckDto; import com.leets.xcellentbe.global.auth.email.EmailRequestDto; import com.leets.xcellentbe.global.auth.email.EmailService; -import com.leets.xcellentbe.global.error.exception.custom.InvalidInputValueException; import com.leets.xcellentbe.global.response.GlobalResponseDto; import io.swagger.v3.oas.annotations.Operation; -import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; @RestController @@ -51,7 +49,9 @@ public ResponseEntity> mailSend(@RequestBody EmailRequ @Operation(summary = "이메일 인증 확인", description = "이메일 인증을 확인합니다.") @PostMapping("/email/check") public ResponseEntity> AuthCheck(@RequestBody EmailCheckDto emailCheckDto) { - return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success(emailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum()))); + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success( + emailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum()))); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/CustomJsonAuthenticationFilter.java b/src/main/java/com/leets/xcellentbe/global/auth/login/CustomJsonAuthenticationFilter.java index 1de5144..a4bfc8b 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/CustomJsonAuthenticationFilter.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/CustomJsonAuthenticationFilter.java @@ -1,6 +1,9 @@ package com.leets.xcellentbe.global.auth.login; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; + import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -9,11 +12,10 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.util.StreamUtils; +import com.fasterxml.jackson.databind.ObjectMapper; + import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Map; /** * 스프링 시큐리티의 폼 기반의 UsernamePasswordAuthenticationFilter를 참고하여 만든 커스텀 필터 @@ -57,9 +59,12 @@ public CustomJsonAuthenticationFilter(ObjectMapper objectMapper) { * (여기서 AuthenticationManager 객체는 ProviderManager -> SecurityConfig에서 설정) */ @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException { - if(request.getContentType() == null || !request.getContentType().equals(CONTENT_TYPE) ) { - throw new AuthenticationServiceException("Authentication Content-Type not supported: " + request.getContentType()); + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws + AuthenticationException, + IOException { + if (request.getContentType() == null || !request.getContentType().equals(CONTENT_TYPE)) { + throw new AuthenticationServiceException( + "Authentication Content-Type not supported: " + request.getContentType()); } String messageBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8); @@ -69,7 +74,8 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ String email = usernamePasswordMap.get(USERNAME_KEY); String password = usernamePasswordMap.get(PASSWORD_KEY); - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(email, password);//principal 과 credentials 전달 + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(email, + password);//principal 과 credentials 전달 return this.getAuthenticationManager().authenticate(authRequest); } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/LoginService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/LoginService.java index 39d5f26..6576daf 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/LoginService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/LoginService.java @@ -2,16 +2,17 @@ import static org.springframework.security.core.userdetails.User.*; -import com.leets.xcellentbe.domain.user.domain.User; -import com.leets.xcellentbe.domain.user.exception.UserNotFoundException; -import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; - -import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; +import com.leets.xcellentbe.domain.user.domain.User; +import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import com.leets.xcellentbe.domain.user.exception.UserNotFoundException; + +import lombok.RequiredArgsConstructor; + @Service @RequiredArgsConstructor public class LoginService implements UserDetailsService { diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginFailureHandler.java b/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginFailureHandler.java index cc54347..500e7d3 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginFailureHandler.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginFailureHandler.java @@ -1,21 +1,21 @@ package com.leets.xcellentbe.global.auth.login.handler; -import lombok.extern.slf4j.Slf4j; +import java.io.IOException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; - import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.leets.xcellentbe.global.error.ErrorCode; import com.leets.xcellentbe.global.response.GlobalResponseDto; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; + /** * JWT 로그인 실패 시 처리하는 핸들러 * SimpleUrlAuthenticationFailureHandler를 상속받아서 구현 @@ -31,8 +31,10 @@ public void onAuthenticationFailure(HttpServletRequest request, HttpServletRespo mapper.registerModule(new JavaTimeModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - ErrorCode errorCode = exception instanceof BadCredentialsException ? ErrorCode.LOGIN_FAIL : ErrorCode.USER_NOT_FOUND; - GlobalResponseDto responseDto = GlobalResponseDto.fail(ErrorCode.valueOf(errorCode.getCode()), errorCode.getMessage()); + ErrorCode errorCode = + exception instanceof BadCredentialsException ? ErrorCode.LOGIN_FAIL : ErrorCode.USER_NOT_FOUND; + GlobalResponseDto responseDto = GlobalResponseDto.fail(ErrorCode.valueOf(errorCode.getCode()), + errorCode.getMessage()); response.setStatus(errorCode.getStatus()); response.setCharacterEncoding("UTF-8"); diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginSuccessHandler.java b/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginSuccessHandler.java index 508cff1..6b501c0 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginSuccessHandler.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/handler/LoginSuccessHandler.java @@ -4,16 +4,12 @@ import java.util.HashMap; import java.util.Map; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import com.fasterxml.jackson.databind.ObjectMapper; - import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; @@ -22,6 +18,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @Slf4j @RequiredArgsConstructor @@ -45,7 +43,8 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo String accessToken = jwtService.createAccessToken(email); // JwtService의 createAccessToken을 사용하여 AccessToken 발급 String refreshToken = jwtService.createRefreshToken(); // JwtService의 createRefreshToken을 사용하여 RefreshToken 발급 - jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); // 응답 헤더에 AccessToken, RefreshToken 실어서 응답 + jwtService.sendAccessAndRefreshToken(response, accessToken, + refreshToken); // 응답 헤더에 AccessToken, RefreshToken 실어서 응답 userRepository.findByEmail(email) .ifPresent(user -> { @@ -69,11 +68,10 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo log.info("로그인에 성공하였습니다. AccessToken : {}", accessToken); log.info("발급된 AccessToken 만료 기간 : {}", accessTokenExpiration); - } private String extractUsername(Authentication authentication) { - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + UserDetails userDetails = (UserDetails)authentication.getPrincipal(); return userDetails.getUsername(); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java index 5251e18..b16a0b1 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java @@ -1,10 +1,11 @@ package com.leets.xcellentbe.global.auth.login.oauth; -import org.springframework.security.oauth2.core.user.DefaultOAuth2User; -import org.springframework.security.core.GrantedAuthority; import java.util.Collection; import java.util.Map; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.core.user.DefaultOAuth2User; + import com.leets.xcellentbe.domain.user.Role; import lombok.Getter; diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java index 7c74a28..e3616bf 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java @@ -1,7 +1,8 @@ package com.leets.xcellentbe.global.auth.login.oauth; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import java.util.Collections; +import java.util.Map; + import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; @@ -10,12 +11,12 @@ import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.Map; - import com.leets.xcellentbe.domain.user.domain.User; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + @Slf4j @Service @RequiredArgsConstructor diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java index 62735b8..c21269e 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java @@ -9,8 +9,9 @@ public class GoogleOAuthUserInfo { public GoogleOAuthUserInfo(Map attributes) { this.attributes = attributes; } + public String getEmail() { - return (String) attributes.get("email"); + return (String)attributes.get("email"); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java index f96c2f9..532d05c 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java @@ -1,14 +1,13 @@ package com.leets.xcellentbe.global.auth.login.oauth; -import lombok.Builder; -import lombok.Getter; - import java.util.Map; -import java.util.UUID; import com.leets.xcellentbe.domain.user.Role; import com.leets.xcellentbe.domain.user.domain.User; +import lombok.Builder; +import lombok.Getter; + @Getter public class OAuthAttributes { @@ -17,7 +16,8 @@ public class OAuthAttributes { private final PasswordUtil passwordUtil; @Builder - private OAuthAttributes(String nameAttributeKey, GoogleOAuthUserInfo googleOAuthUserInfo, PasswordUtil passwordUtil) { + private OAuthAttributes(String nameAttributeKey, GoogleOAuthUserInfo googleOAuthUserInfo, + PasswordUtil passwordUtil) { this.nameAttributeKey = nameAttributeKey; this.googleOAuthUserInfo = googleOAuthUserInfo; this.passwordUtil = passwordUtil; diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java index 39769a9..7fa8d44 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java @@ -1,20 +1,14 @@ package com.leets.xcellentbe.global.auth.login.oauth; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - - import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -24,56 +18,63 @@ import com.leets.xcellentbe.global.auth.jwt.JwtService; import com.leets.xcellentbe.global.response.GlobalResponseDto; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + @Slf4j @Component @RequiredArgsConstructor public class OAuthLoginSuccessHandler implements AuthenticationSuccessHandler { - private final JwtService jwtService; - private final UserRepository userRepository; + private final JwtService jwtService; + private final UserRepository userRepository; - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - log.info("OAuth2 Login 성공!"); + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + log.info("OAuth2 Login 성공!"); - Map tokenMap = new HashMap<>(); + Map tokenMap = new HashMap<>(); - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); - mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - CustomOAuthUser oAuth2User = (CustomOAuthUser) authentication.getPrincipal(); - Optional user = userRepository.findByEmail(oAuth2User.getEmail()); - // User의 Role이 GUEST일 경우 처음 요청한 회원이므로 회원가입 페이지로 리다이렉트 - if (oAuth2User.getRole() == Role.GUEST) { - String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); + CustomOAuthUser oAuth2User = (CustomOAuthUser)authentication.getPrincipal(); + Optional user = userRepository.findByEmail(oAuth2User.getEmail()); + // User의 Role이 GUEST일 경우 처음 요청한 회원이므로 회원가입 페이지로 리다이렉트 + if (oAuth2User.getRole() == Role.GUEST) { + String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); - tokenMap.put("accessToken", accessToken); - GlobalResponseDto> responseDto = GlobalResponseDto.success(tokenMap); + tokenMap.put("accessToken", accessToken); + GlobalResponseDto> responseDto = GlobalResponseDto.success(tokenMap); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); - String json = mapper.writeValueAsString(responseDto); + String json = mapper.writeValueAsString(responseDto); - response.getWriter().write(json); - // response.sendRedirect("/oauth2/sign-up.html"); + response.getWriter().write(json); + // response.sendRedirect("/oauth2/sign-up.html"); - jwtService.sendAccessAndRefreshToken(response, accessToken, null); - } else { - loginSuccess(response, oAuth2User); // 로그인에 성공한 경우 access, refresh 토큰 생성 - } - } + jwtService.sendAccessAndRefreshToken(response, accessToken, null); + } else { + loginSuccess(response, oAuth2User); // 로그인에 성공한 경우 access, refresh 토큰 생성 + } + } - private void loginSuccess(HttpServletResponse response, CustomOAuthUser oAuth2User) throws IOException { - String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); - String refreshToken = jwtService.createRefreshToken(); - response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); - response.addHeader(jwtService.getRefreshHeader(), "Bearer " + refreshToken); + private void loginSuccess(HttpServletResponse response, CustomOAuthUser oAuth2User) throws IOException { + String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); + String refreshToken = jwtService.createRefreshToken(); + response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); + response.addHeader(jwtService.getRefreshHeader(), "Bearer " + refreshToken); - jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); - jwtService.updateRefreshToken(oAuth2User.getEmail(), refreshToken); - } + jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); + jwtService.updateRefreshToken(oAuth2User.getEmail(), refreshToken); + } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java index 7c21841..098b67d 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java @@ -1,6 +1,7 @@ package com.leets.xcellentbe.global.auth.login.oauth; import java.security.SecureRandom; + import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -15,6 +16,14 @@ public PasswordUtil() { this.passwordEncoder = new BCryptPasswordEncoder(); } + public static void main(String[] args) { + PasswordUtil passwordUtil = new PasswordUtil(); + + // 랜덤 비밀번호 생성 및 해싱 + String hashedPassword = passwordUtil.generateHashedRandomPassword(); + System.out.println("해싱된 랜덤 비밀번호: " + hashedPassword); + } + // 랜덤 비밀번호 생성 및 해싱하여 반환 public String generateHashedRandomPassword() { String randomPassword = generateRandomPassword(); @@ -38,12 +47,4 @@ private String generateRandomPassword() { private String hashPassword(String password) { return passwordEncoder.encode(password); } - - public static void main(String[] args) { - PasswordUtil passwordUtil = new PasswordUtil(); - - // 랜덤 비밀번호 생성 및 해싱 - String hashedPassword = passwordUtil.generateHashedRandomPassword(); - System.out.println("해싱된 랜덤 비밀번호: " + hashedPassword); - } } diff --git a/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java b/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java index 44bb014..da97feb 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java @@ -1,12 +1,13 @@ package com.leets.xcellentbe.global.config; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.AmazonS3ClientBuilder; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; @Configuration public class AwsConfig { @@ -27,7 +28,7 @@ public class AwsConfig { @Bean public AmazonS3Client amazonS3Client() { BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey); - return (AmazonS3Client) AmazonS3ClientBuilder.standard() + return (AmazonS3Client)AmazonS3ClientBuilder.standard() .withRegion(region) .withCredentials(new AWSStaticCredentialsProvider(awsCreds)) .build(); diff --git a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java index aa94435..677c83e 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java @@ -1,6 +1,8 @@ package com.leets.xcellentbe.global.config; -import lombok.RequiredArgsConstructor; +import static org.springframework.security.config.Customizer.*; + +import java.util.Arrays; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -21,20 +23,17 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import com.fasterxml.jackson.databind.ObjectMapper; - -import static org.springframework.security.config.Customizer.withDefaults; - -import java.util.Arrays; - import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import com.leets.xcellentbe.global.auth.jwt.JwtAuthenticationFilter; import com.leets.xcellentbe.global.auth.jwt.JwtService; import com.leets.xcellentbe.global.auth.login.CustomJsonAuthenticationFilter; import com.leets.xcellentbe.global.auth.login.LoginService; import com.leets.xcellentbe.global.auth.login.handler.LoginFailureHandler; import com.leets.xcellentbe.global.auth.login.handler.LoginSuccessHandler; -import com.leets.xcellentbe.global.auth.jwt.JwtAuthenticationFilter; import com.leets.xcellentbe.global.auth.login.oauth.OAuthLoginSuccessHandler; +import lombok.RequiredArgsConstructor; + @Configuration @EnableWebSecurity @RequiredArgsConstructor @@ -77,11 +76,11 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2.successHandler(oAuthLoginSuccessHandler)); - // .failureHandler(oAuth2LoginFailureHandler) - http.addFilterAfter(customJsonAuthenticationFilter(), LogoutFilter.class); - http.addFilterBefore(jwtAuthenticationFilter(), CustomJsonAuthenticationFilter.class); + // .failureHandler(oAuth2LoginFailureHandler) + http.addFilterAfter(customJsonAuthenticationFilter(), LogoutFilter.class); + http.addFilterBefore(jwtAuthenticationFilter(), CustomJsonAuthenticationFilter.class); - return http.build(); + return http.build(); } @Bean diff --git a/src/main/java/com/leets/xcellentbe/global/config/swagger/SwaggerConfig.java b/src/main/java/com/leets/xcellentbe/global/config/swagger/SwaggerConfig.java index a90bd15..612f91d 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/swagger/SwaggerConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/swagger/SwaggerConfig.java @@ -19,26 +19,26 @@ version = "v1.0.0")) @Configuration public class SwaggerConfig { - @Bean - public OpenAPI openAPI() { - SecurityScheme securityScheme = getSecurityScheme(); - SecurityRequirement securityRequirement = getSecurityRequireMent(); + @Bean + public OpenAPI openAPI() { + SecurityScheme securityScheme = getSecurityScheme(); + SecurityRequirement securityRequirement = getSecurityRequireMent(); - Server server = new Server(); + Server server = new Server(); server.setUrl("/"); - return new OpenAPI() - .servers(List.of(server)) - .components(new Components().addSecuritySchemes("jwt token", securityScheme)) - .security(List.of(securityRequirement)); - } + return new OpenAPI() + .servers(List.of(server)) + .components(new Components().addSecuritySchemes("jwt token", securityScheme)) + .security(List.of(securityRequirement)); + } - private SecurityScheme getSecurityScheme() { - return new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT") - .in(SecurityScheme.In.HEADER).name("Authorization"); - } + private SecurityScheme getSecurityScheme() { + return new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT") + .in(SecurityScheme.In.HEADER).name("Authorization"); + } - private SecurityRequirement getSecurityRequireMent() { - return new SecurityRequirement().addList("bearer"); - } + private SecurityRequirement getSecurityRequireMent() { + return new SecurityRequirement().addList("bearer"); + } } diff --git a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java index 6ce72fd..95a4df6 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java +++ b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java @@ -11,19 +11,18 @@ public enum ErrorCode { INVALID_FILE_FORMAT(400, "INVALID_FILE_FORMAT", "올바르지 않은 파일 형식입니다."), INVALID_TOKEN(401, "INVALID_TOKEN", "유효하지 않은 토큰입니다."), LOGIN_FAIL(401, "LOGIN_FAIL", "로그인에 실패하였습니다."), - CHAT_ROOM_FORBIDDEN(403, "CHAT_ROOM_FORBIDDEN","권한이 없는 채팅방입니다."), + CHAT_ROOM_FORBIDDEN(403, "CHAT_ROOM_FORBIDDEN", "권한이 없는 채팅방입니다."), USER_NOT_FOUND(404, "USER_NOT_FOUND", "유저를 찾을 수 없습니다."), EXPIRED_TOKEN(403, "EXPIRED_TOKEN", "만료된 토큰입니다."), FOLLOW_OPERATION_ERROR(409, "FOLLOW_OPERATION_ERROR", "적절하지 않은 팔로우 요청입니다."), - USER_ALREADY_EXISTS(412 , "ALREADY_EXISTS_EXCEPTION" , "이미 존재하는 사용자입니다." ), + USER_ALREADY_EXISTS(412, "ALREADY_EXISTS_EXCEPTION", "이미 존재하는 사용자입니다."), ARTICLE_NOT_FOUND(404, "ARTICLE_NOT_FOUND", "게시물을 찾을 수 없습니다."), CHAT_ROOM_NOT_FOUND(404, "CHAT_ROOM_NOT_FOUND", "채팅방을 찾을 수 없습니다."), - REJECT_DUPLICATION(409,"REJECT_DUPLICATION","중복된 값입니다."), + REJECT_DUPLICATION(409, "REJECT_DUPLICATION", "중복된 값입니다."), AUTH_CODE_ALREADY_SENT(429, "AUTH_CODE_ALREADY_SENT", "이미 인증번호를 전송했습니다."), INTERNAL_SERVER_ERROR(500, "INTERNAL_SERVER_ERROR", "서버 오류가 발생했습니다."), EMAIL_CANNOT_BE_SENT(500, "EMAIL_CANNOT_BE_SENT", "이메일 전송에 실패했습니다."); - private final int status; private final String code; private final String message; diff --git a/src/main/java/com/leets/xcellentbe/global/error/ErrorResponse.java b/src/main/java/com/leets/xcellentbe/global/error/ErrorResponse.java index fa3001f..f42f3cd 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/ErrorResponse.java +++ b/src/main/java/com/leets/xcellentbe/global/error/ErrorResponse.java @@ -13,6 +13,7 @@ public ErrorResponse(ErrorCode errorCode) { this.message = errorCode.getMessage(); this.code = errorCode.getCode(); } + public static ErrorResponse of(ErrorCode errorCode) { return new ErrorResponse(errorCode); } diff --git a/src/main/java/com/leets/xcellentbe/global/response/GlobalResponseDto.java b/src/main/java/com/leets/xcellentbe/global/response/GlobalResponseDto.java index 149268f..87f1532 100644 --- a/src/main/java/com/leets/xcellentbe/global/response/GlobalResponseDto.java +++ b/src/main/java/com/leets/xcellentbe/global/response/GlobalResponseDto.java @@ -1,5 +1,7 @@ package com.leets.xcellentbe.global.response; +import java.time.LocalDateTime; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -10,8 +12,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; - @Getter @NoArgsConstructor public class GlobalResponseDto { @@ -31,11 +31,6 @@ public GlobalResponseDto(boolean isSuccess, int code, LocalDateTime timestamp, S this.message = message; this.result = result; } - public String toJson() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); - return mapper.writeValueAsString(this); - } // 201 Create 성공 응답 public static GlobalResponseDto success(T result, int code) { @@ -58,6 +53,7 @@ public static GlobalResponseDto success(T result) { .result(result) .build(); } + //성공 응답 result 없이 public static GlobalResponseDto success() { return GlobalResponseDto.builder() @@ -68,6 +64,7 @@ public static GlobalResponseDto success() { .result(null) .build(); } + // 실패 응답 public static GlobalResponseDto fail(ErrorCode code, String message) { return GlobalResponseDto.builder() @@ -78,4 +75,10 @@ public static GlobalResponseDto fail(ErrorCode code, String message) { .result(null) .build(); } + + public String toJson() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + return mapper.writeValueAsString(this); + } } From e11303658b3d2c8c793694664ec2ba3ec096c546 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 22 Oct 2024 00:13:15 +0900 Subject: [PATCH 08/14] =?UTF-8?q?refactor:=20#13=20DTO=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/follow/controller/FollowController.java | 6 +++--- ...wingResponseDto.java => FollowInfoResponseDto.java} | 8 ++++---- .../domain/follow/service/FollowService.java | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/main/java/com/leets/xcellentbe/domain/follow/dto/{FollowerAndFollowingResponseDto.java => FollowInfoResponseDto.java} (65%) diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java index d7b2af3..847101b 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/controller/FollowController.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController; import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; -import com.leets.xcellentbe.domain.follow.dto.FollowerAndFollowingResponseDto; +import com.leets.xcellentbe.domain.follow.dto.FollowInfoResponseDto; import com.leets.xcellentbe.domain.follow.service.FollowService; import com.leets.xcellentbe.global.response.GlobalResponseDto; @@ -46,7 +46,7 @@ public ResponseEntity> unfollowerUser(@Reque @GetMapping("/following") @Operation(summary = "팔로잉 조회", description = "사용자가 팔로우하는 사용자 목록을 조회합니다.") - public ResponseEntity>> getFollowingList( + public ResponseEntity>> getFollowingList( @RequestParam(required = false, defaultValue = "1") int pageNo, @RequestParam String customId) { return ResponseEntity.status(HttpStatus.OK) .body(GlobalResponseDto.success(followService.getFollowingList(customId, pageNo - 1))); @@ -54,7 +54,7 @@ public ResponseEntity>> @GetMapping("/follower") @Operation(summary = "팔로워 조회", description = "사용자를 팔로우하는 사용자 목록을 조회합니다.") - public ResponseEntity>> getFollowerList( + public ResponseEntity>> getFollowerList( @RequestParam(required = false, defaultValue = "1") int pageNo, @RequestParam String customId) { return ResponseEntity.status(HttpStatus.OK) .body(GlobalResponseDto.success(followService.getFollowerList(customId, pageNo - 1))); diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowInfoResponseDto.java similarity index 65% rename from src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java rename to src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowInfoResponseDto.java index da6f18c..dda55b2 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowerAndFollowingResponseDto.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/dto/FollowInfoResponseDto.java @@ -7,19 +7,19 @@ import lombok.Getter; @Getter -public class FollowerAndFollowingResponseDto { +public class FollowInfoResponseDto { private String customId; private String userName; @Builder - public FollowerAndFollowingResponseDto(String customId, String userName) { + public FollowInfoResponseDto(String customId, String userName) { this.customId = customId; this.userName = userName; } - public static FollowerAndFollowingResponseDto from(Follow follow) { + public static FollowInfoResponseDto from(Follow follow) { User user = follow.getFollowing(); - return FollowerAndFollowingResponseDto.builder() + return FollowInfoResponseDto.builder() .customId(user.getCustomId()) .userName(user.getUserName()) .build(); diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java index 3184076..474b183 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -11,7 +11,7 @@ import com.leets.xcellentbe.domain.follow.domain.Follow; import com.leets.xcellentbe.domain.follow.domain.repository.FollowRepository; import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; -import com.leets.xcellentbe.domain.follow.dto.FollowerAndFollowingResponseDto; +import com.leets.xcellentbe.domain.follow.dto.FollowInfoResponseDto; import com.leets.xcellentbe.domain.follow.exception.FollowOperationError; import com.leets.xcellentbe.domain.user.domain.User; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; @@ -61,21 +61,21 @@ public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request } // 팔로잉 목록 조회 - public Page getFollowingList(String customId, int pageNo) { + public Page getFollowingList(String customId, int pageNo) { User user = findUserByCustomId(customId); Pageable pageable = createPageable(pageNo); return followRepository.findByFollower(user, pageable) - .map(FollowerAndFollowingResponseDto::from); + .map(FollowInfoResponseDto::from); } // 팔로워 목록 조회 - public Page getFollowerList(String customId, int pageNo) { + public Page getFollowerList(String customId, int pageNo) { User user = findUserByCustomId(customId); Pageable pageable = createPageable(pageNo); return followRepository.findByFollowing(user, pageable) - .map(FollowerAndFollowingResponseDto::from); + .map(FollowInfoResponseDto::from); } // 커스텀아이디로 유저 검색 From 0558795eaea3e44880cfedab7f3549f4c3a13ddf Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Wed, 23 Oct 2024 22:07:20 +0900 Subject: [PATCH 09/14] =?UTF-8?q?refactor:=20#13=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/service/UserService.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java index 5bbba35..442966c 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java @@ -1,7 +1,5 @@ package com.leets.xcellentbe.domain.user.service; -import java.util.Optional; - import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -102,16 +100,13 @@ public String updateBackgroundProfileImage(MultipartFile multipartFile, HttpServ //JWT 토큰 해독하여 사용자 정보 반환 메소드 private User getUser(HttpServletRequest request) { - Optional user = jwtService.extractAccessToken(request) + User user = jwtService.extractAccessToken(request) .filter(jwtService::isTokenValid) - .flatMap(accessToken -> jwtService.extractEmail(accessToken)) - .flatMap(email -> userRepository.findByEmail(email)); - - if (user.isEmpty()) { - throw new UserNotFoundException(); - } + .flatMap(jwtService::extractEmail) + .flatMap(userRepository::findByEmail) + .orElseThrow(UserNotFoundException::new); - return user.get(); + return user; } } From ba26077ef0155efb10a653f72a84c6d7be0de742 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Wed, 23 Oct 2024 22:29:04 +0900 Subject: [PATCH 10/14] =?UTF-8?q?refactor:=20#13=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/follow/service/FollowService.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java index 474b183..75d9793 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -1,7 +1,5 @@ package com.leets.xcellentbe.domain.follow.service; -import java.util.Optional; - import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -10,8 +8,8 @@ import com.leets.xcellentbe.domain.follow.domain.Follow; import com.leets.xcellentbe.domain.follow.domain.repository.FollowRepository; -import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; import com.leets.xcellentbe.domain.follow.dto.FollowInfoResponseDto; +import com.leets.xcellentbe.domain.follow.dto.FollowRequestDto; import com.leets.xcellentbe.domain.follow.exception.FollowOperationError; import com.leets.xcellentbe.domain.user.domain.User; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; @@ -91,15 +89,12 @@ private Pageable createPageable(int pageNo) { //JWT 토큰 해독하여 사용자 정보 반환 메소드 private User getUser(HttpServletRequest request) { - Optional user = jwtService.extractAccessToken(request) + User user = jwtService.extractAccessToken(request) .filter(jwtService::isTokenValid) - .flatMap(accessToken -> jwtService.extractEmail(accessToken)) - .flatMap(userRepository::findByEmail); - - if (user.isEmpty()) { - throw new UserNotFoundException(); - } + .flatMap(jwtService::extractEmail) + .flatMap(userRepository::findByEmail) + .orElseThrow(UserNotFoundException::new); - return user.get(); + return user; } } From 5e9064af345eb1e37598c315b361c711200fd9ab Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Wed, 23 Oct 2024 22:41:58 +0900 Subject: [PATCH 11/14] =?UTF-8?q?fix:=20#13=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/leets/xcellentbe/domain/user/domain/User.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java index dc80407..a32fd12 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java @@ -121,7 +121,7 @@ public void updateProfile(String userName, String phoneNumber, String customId, this.websiteUrl = websiteUrl; this.location = location; this.phoneNumber = phoneNumber; - this.userBirth = userBirth; + this.userBirth = BirthDay.builder().day(userBirthDay).year(userBirthYear).month(userBirthMonth).build(); } public void updateProfileImage(String updateProfileImageUrl) { From f3daa5dced72ec1abc1ca3432ac49b6869f464cf Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Wed, 23 Oct 2024 22:47:22 +0900 Subject: [PATCH 12/14] =?UTF-8?q?feat:=20#13=20Follow=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=83=9D=EC=84=B1/=EC=88=98=EC=A0=95=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/leets/xcellentbe/domain/follow/domain/Follow.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java b/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java index 7b09b93..5251420 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/domain/Follow.java @@ -1,5 +1,6 @@ package com.leets.xcellentbe.domain.follow.domain; +import com.leets.xcellentbe.domain.shared.BaseTimeEntity; import com.leets.xcellentbe.domain.user.domain.User; import jakarta.persistence.Entity; @@ -18,7 +19,7 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Follow { +public class Follow extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From bede5f1b46f05ca096e3b05c39922900ca09d790 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sat, 26 Oct 2024 20:29:23 +0900 Subject: [PATCH 13/14] =?UTF-8?q?fix:=20#13=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=9B=90=EC=83=81=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../error/exception/GlobalExceptionHandler.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java b/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java index 48a5493..314885b 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java @@ -19,13 +19,14 @@ private static void showErrorLog(ErrorCode errorCode) { log.error("errorCode: {}, message: {}", errorCode.getCode(), errorCode.getMessage()); } - // @ExceptionHandler(Exception.class) - // public ResponseEntity handleGenericException(Exception ex) { - // ErrorCode errorCode = ErrorCode.INTERNAL_SERVER_ERROR; - // ErrorResponse errorResponse = new ErrorResponse(errorCode); - // showErrorLog(errorCode); - // return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())).body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); - // } + @ExceptionHandler(Exception.class) + public ResponseEntity handleGenericException(Exception ex) { + ErrorCode errorCode = ErrorCode.INTERNAL_SERVER_ERROR; + ErrorResponse errorResponse = new ErrorResponse(errorCode); + showErrorLog(errorCode); + return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())) + .body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); + } @ExceptionHandler(CommonException.class) // Custom Exception을 포괄적으로 처리 public ResponseEntity> handleCommonException(CommonException ex) { From 8df1e9f9929d20bb1c61e22b7cbd60f494cf1ef8 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 29 Oct 2024 13:32:13 +0900 Subject: [PATCH 14/14] =?UTF-8?q?refactor:=20#13=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EC=B6=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/follow/service/FollowService.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java index 75d9793..8621ee9 100644 --- a/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java +++ b/src/main/java/com/leets/xcellentbe/domain/follow/service/FollowService.java @@ -33,12 +33,9 @@ public class FollowService { // 팔로우 public void followUser(FollowRequestDto requestDto, HttpServletRequest request) { User user = getUser(request); - User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) - .orElseThrow(UserNotFoundException::new); + User targetUser = getTargetUser(requestDto); - boolean isFollowing = followRepository.findByFollowerAndFollowing(user, targetUser).isPresent(); - - if (isFollowing) { + if (isFollowing(user, targetUser)) { throw new FollowOperationError(); } @@ -46,16 +43,33 @@ public void followUser(FollowRequestDto requestDto, HttpServletRequest request) followRepository.save(follow); } + // 이미 팔로우 중인지 확인 + private boolean isFollowing(User user, User targetUser) { + return followRepository.findByFollowerAndFollowing(user, targetUser).isPresent(); + } + // 언팔로우 public void unfollowUser(FollowRequestDto requestDto, HttpServletRequest request) { User user = getUser(request); - User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) - .orElseThrow(UserNotFoundException::new); + User targetUser = getTargetUser(requestDto); + + Follow follow = getFollowRelation(user, targetUser); + followRepository.delete(follow); + } + + // 팔로우 관계 조회 + private Follow getFollowRelation(User user, User targetUser) { Follow follow = followRepository.findByFollowerAndFollowing(user, targetUser) .orElseThrow(FollowOperationError::new); + return follow; + } - followRepository.delete(follow); + // 팔로우(언팔로우) 대상 유저 조회 + private User getTargetUser(FollowRequestDto requestDto) { + User targetUser = userRepository.findByCustomId(requestDto.getCustomId()) + .orElseThrow(UserNotFoundException::new); + return targetUser; } // 팔로잉 목록 조회