Skip to content

Commit d82baef

Browse files
authored
♻️ [Refactor] 마이페이지, 충전 API 검증 어노테이션 추가
2 parents 9c92727 + 110e5fc commit d82baef

8 files changed

Lines changed: 62 additions & 21 deletions

File tree

src/main/java/com/example/scoi/domain/charge/controller/ChargeController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.example.scoi.global.apiPayload.ApiResponse;
1010
import com.example.scoi.global.apiPayload.code.BaseSuccessCode;
1111
import com.example.scoi.global.security.userdetails.CustomUserDetails;
12+
import jakarta.validation.Valid;
1213
import lombok.RequiredArgsConstructor;
1314
import lombok.extern.slf4j.Slf4j;
1415
import org.springframework.security.core.annotation.AuthenticationPrincipal;
@@ -28,7 +29,7 @@ public class ChargeController implements ChargeControllerDocs{
2829
@PostMapping("/deposits/krw")
2930
public ApiResponse<ChargeResDTO.ChargeKrw> chargeKrw(
3031
@AuthenticationPrincipal CustomUserDetails user,
31-
@RequestBody ChargeReqDTO.ChargeKrw dto
32+
@Valid @RequestBody ChargeReqDTO.ChargeKrw dto
3233
){
3334
BaseSuccessCode code = ChargeSuccessCode.OK;
3435
return ApiResponse.onSuccess(code, chargeService.chargeKrw(user.getUsername(),dto));
@@ -38,7 +39,7 @@ public ApiResponse<ChargeResDTO.ChargeKrw> chargeKrw(
3839
@PostMapping("/deposits")
3940
public ApiResponse<String> getOrders(
4041
@AuthenticationPrincipal CustomUserDetails user,
41-
@RequestBody ChargeReqDTO.GetOrder dto
42+
@Valid @RequestBody ChargeReqDTO.GetOrder dto
4243
){
4344
BaseSuccessCode code = ChargeSuccessCode.OK;
4445
return ApiResponse.onSuccess(code, chargeService.getOrders(user.getUsername(), dto));
@@ -78,7 +79,7 @@ public ApiResponse<String> getDepositAddress(
7879
@PostMapping("/deposits/address")
7980
public ApiResponse<List<String>> createDepositAddress(
8081
@AuthenticationPrincipal CustomUserDetails user,
81-
@RequestBody ChargeReqDTO.CreateDepositAddress dto
82+
@Valid @RequestBody ChargeReqDTO.CreateDepositAddress dto
8283
){
8384
BaseSuccessCode code = ChargeSuccessCode.OK;
8485
return ApiResponse.onSuccess(code, chargeService.createDepositAddress(user.getUsername(), dto));

src/main/java/com/example/scoi/domain/charge/controller/ChargeControllerDocs.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.example.scoi.global.security.userdetails.CustomUserDetails;
99
import io.swagger.v3.oas.annotations.Operation;
1010
import io.swagger.v3.oas.annotations.tags.Tag;
11+
import jakarta.validation.Valid;
1112
import org.springframework.security.core.annotation.AuthenticationPrincipal;
1213
import org.springframework.web.bind.annotation.RequestBody;
1314
import org.springframework.web.bind.annotation.RequestParam;
@@ -21,13 +22,13 @@ public interface ChargeControllerDocs {
2122
summary = "원화 충전 요청하기 API By 김주헌",
2223
description = "코인을 구매하기 위한 원화 충전을 요청합니다. 반드시 인증서 발급을 한 뒤 호출해주세요."
2324
)
24-
ApiResponse<ChargeResDTO.ChargeKrw> chargeKrw(@AuthenticationPrincipal CustomUserDetails user, @RequestBody ChargeReqDTO.ChargeKrw dto);
25+
ApiResponse<ChargeResDTO.ChargeKrw> chargeKrw(@AuthenticationPrincipal CustomUserDetails user, @Valid @RequestBody ChargeReqDTO.ChargeKrw dto);
2526

2627
@Operation(
2728
summary = "특정 주문 확인하기 API By 김주헌",
2829
description = "특정 주문을 UUID로 스냅샷 형태로 확인합니다. 주문 체결 알림은 웹소켓 이용해서 실시간 추적, 체결 되면 FCM 토큰으로 알림이 갑니다."
2930
)
30-
ApiResponse<String> getOrders(@AuthenticationPrincipal CustomUserDetails user, @RequestBody ChargeReqDTO.GetOrder dto);
31+
ApiResponse<String> getOrders(@AuthenticationPrincipal CustomUserDetails user, @Valid @RequestBody ChargeReqDTO.GetOrder dto);
3132

3233
@Operation(
3334
summary = "보유 자산 조회 API By 강서현",
@@ -52,10 +53,18 @@ ApiResponse<String> getDepositAddress(
5253
description = """
5354
코인의 입금 주소를 생성합니다.
5455
각 거래소에 생성 요청을 보내기때문에 입금 주소가 즉시 안 올 수 있습니다. (비동기)
55-
따라서 주소가 필요하면 생성 → 조회 순으로 요청을 보내주세요"""
56+
따라서 주소가 필요하면 생성 → 조회 순으로 요청을 보내주세요
57+
58+
** 거래소 별 가능한 코인 심볼 - 네트워크 타입
59+
업비트 USDT: [ETH, TRX, APT, KAIA]
60+
업비트 USDC: [ETH, SOL]
61+
빗썸 USDT: [ETH, TRX, APT, KAIA]
62+
빗썸 USDC: [ETH]
63+
**
64+
"""
5665
)
5766
ApiResponse<List<String>> createDepositAddress(
5867
@AuthenticationPrincipal CustomUserDetails user,
59-
@RequestBody ChargeReqDTO.CreateDepositAddress dto
68+
@Valid @RequestBody ChargeReqDTO.CreateDepositAddress dto
6069
);
6170
}

src/main/java/com/example/scoi/domain/charge/dto/ChargeReqDTO.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,41 @@
33
import com.example.scoi.domain.charge.enums.DepositType;
44
import com.example.scoi.domain.charge.enums.MFAType;
55
import com.example.scoi.domain.member.enums.ExchangeType;
6+
import jakarta.validation.constraints.NotBlank;
7+
import jakarta.validation.constraints.NotNull;
68

79
import java.util.List;
810

911
public class ChargeReqDTO {
1012

1113
// 원화 입금
1214
public record ChargeKrw(
15+
@NotNull(message = "거래소 타입은 필수입니다. (BITHUMB, UPBIT)")
1316
ExchangeType exchangeType,
17+
@NotNull(message = "충전할 금액은 필수입니다.")
1418
Long amount,
19+
@NotNull(message = "인증서 타입은 필수입니다. (KAKAO, NAVER, HANA)")
1520
MFAType MFA
1621
){}
1722

1823
// 특정 주문 확인하기
1924
public record GetOrder(
25+
@NotNull(message = "거래소 타입은 필수입니다.")
2026
ExchangeType exchangeType,
27+
@NotNull(message = "UUID는 필수입니다.")
28+
@NotBlank(message = "UUID가 빈칸일 수 없습니다.")
2129
String uuid,
30+
@NotNull(message = "거래 타입은 필수입니다.")
2231
DepositType depositType
2332
){}
2433

2534
// 입금 주소 생성하기
2635
public record CreateDepositAddress(
36+
@NotNull(message = "거래소 타입은 필수입니다.")
2737
ExchangeType exchangeType,
38+
@NotNull(message = "코인 타입은 필수입니다.")
2839
List<String> coinType,
40+
@NotNull(message = "네트워크 타입은 필수입니다.")
2941
List<String> netType
3042
){}
3143
}

src/main/java/com/example/scoi/domain/charge/service/ChargeService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public ChargeResDTO.ChargeKrw chargeKrw(
4747
if (dto.exchangeType().equals(ExchangeType.BITHUMB) && !dto.MFA().equals(MFAType.KAKAO)){
4848
throw new ChargeException(ChargeErrorCode.INVALIDED_TWO_FACTOR_AUTH);
4949
}
50+
5051
// 거래소별 분기
5152
String token;
5253
String uuid, txid;

src/main/java/com/example/scoi/domain/member/controller/MemberController.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.example.scoi.global.apiPayload.code.BaseSuccessCode;
1010
import com.example.scoi.global.apiPayload.code.GeneralErrorCode;
1111
import com.example.scoi.global.security.userdetails.CustomUserDetails;
12+
import jakarta.validation.Valid;
1213
import lombok.RequiredArgsConstructor;
1314
import org.springframework.security.core.annotation.AuthenticationPrincipal;
1415
import org.springframework.web.bind.annotation.*;
@@ -36,7 +37,7 @@ public ApiResponse<MemberResDTO.MemberInfo> getMemberInfo(
3637
// 간편 비밀번호 변경
3738
@PatchMapping("/members/me/password")
3839
public ApiResponse<Map<String, String>> changePassword(
39-
@RequestBody MemberReqDTO.ChangePassword dto,
40+
@Valid @RequestBody MemberReqDTO.ChangePassword dto,
4041
@AuthenticationPrincipal CustomUserDetails user
4142
){
4243
Optional<Map<String, String>> result = memberService.changePassword(dto, user.getUsername());
@@ -75,7 +76,7 @@ public ApiResponse<List<MemberResDTO.ApiKeyList>> getApiKeyList(
7576
@PostMapping("/members/me/api-keys")
7677
public ApiResponse<List<String>> postPatchApiKey(
7778
@AuthenticationPrincipal CustomUserDetails user,
78-
@RequestBody List<MemberReqDTO.PostPatchApiKey> dto
79+
@Valid @RequestBody List<MemberReqDTO.PostPatchApiKey> dto
7980
){
8081
BaseSuccessCode code = MemberSuccessCode.POST_PATCH_API_KEY;
8182
List<String> result = memberService.postPatchApiKey(user.getUsername(), dto);
@@ -89,7 +90,7 @@ public ApiResponse<List<String>> postPatchApiKey(
8990
@DeleteMapping("/members/me/api-keys")
9091
public ApiResponse<Void> deleteApiKey(
9192
@AuthenticationPrincipal CustomUserDetails user,
92-
@RequestBody MemberReqDTO.DeleteApiKey dto
93+
@Valid @RequestBody MemberReqDTO.DeleteApiKey dto
9394
){
9495
BaseSuccessCode code = MemberSuccessCode.DELETE_API_KEY;
9596
return ApiResponse.onSuccess(code, memberService.deleteApiKey(user.getUsername(), dto));
@@ -99,7 +100,7 @@ public ApiResponse<Void> deleteApiKey(
99100
@PostMapping("/members/me/fcm")
100101
public ApiResponse<Void> postFcmToken(
101102
@AuthenticationPrincipal CustomUserDetails user,
102-
@RequestBody MemberReqDTO.PostFcmToken dto
103+
@Valid @RequestBody MemberReqDTO.PostFcmToken dto
103104
){
104105
BaseSuccessCode code = MemberSuccessCode.POST_PATCH_FCM_TOKEN;
105106
return ApiResponse.onSuccess(code, memberService.postFcmToken(user.getUsername(), dto));

src/main/java/com/example/scoi/domain/member/controller/MemberControllerDocs.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.example.scoi.global.security.userdetails.CustomUserDetails;
77
import io.swagger.v3.oas.annotations.Operation;
88
import io.swagger.v3.oas.annotations.tags.Tag;
9+
import jakarta.validation.Valid;
910
import org.springframework.security.core.annotation.AuthenticationPrincipal;
1011
import org.springframework.web.bind.annotation.RequestBody;
1112

@@ -26,7 +27,7 @@ public interface MemberControllerDocs {
2627
summary = "간편 비밀번호 변경 API By 김주헌",
2728
description = "간편 비밀번호를 변경합니다."
2829
)
29-
ApiResponse<Map<String, String>> changePassword(@RequestBody MemberReqDTO.ChangePassword dto, @AuthenticationPrincipal CustomUserDetails user) throws GeneralSecurityException;
30+
ApiResponse<Map<String, String>> changePassword(@Valid @RequestBody MemberReqDTO.ChangePassword dto, @AuthenticationPrincipal CustomUserDetails user) throws GeneralSecurityException;
3031

3132
@Operation(
3233
summary = "거래소 목록 조회 API By 김주헌",
@@ -42,19 +43,20 @@ public interface MemberControllerDocs {
4243

4344
@Operation(
4445
summary = "API키 등록 및 수정 API By 김주헌",
45-
description = "연동된 거래소의 API키를 등록 및 수정을 합니다."
46+
description = "연동된 거래소의 API키를 등록 및 수정을 합니다. 등록, 수정 적용이 되었을 경우 해당 거래소 타입을 result에 담아 보냅니다."
4647
)
47-
ApiResponse<List<String>> postPatchApiKey(@AuthenticationPrincipal CustomUserDetails user, @RequestBody List<MemberReqDTO.PostPatchApiKey> dto);
48+
ApiResponse<List<String>> postPatchApiKey(@AuthenticationPrincipal CustomUserDetails user, @Valid @RequestBody List<MemberReqDTO.PostPatchApiKey> dto);
4849

4950
@Operation(
5051
summary = "API키 삭제 API By 김주헌",
5152
description = "연동된 거래소의 API키를 삭제합니다."
5253
)
53-
ApiResponse<Void> deleteApiKey(@AuthenticationPrincipal CustomUserDetails user, @RequestBody MemberReqDTO.DeleteApiKey dto);
54+
ApiResponse<Void> deleteApiKey(@AuthenticationPrincipal CustomUserDetails user, @Valid @RequestBody MemberReqDTO.DeleteApiKey dto);
55+
5456

5557
@Operation(
5658
summary = "FCM 토큰 등록 API By 김주헌",
5759
description = "FCM 토큰을 등록합니다."
5860
)
59-
ApiResponse<Void> postFcmToken(@AuthenticationPrincipal CustomUserDetails user, @RequestBody MemberReqDTO.PostFcmToken dto);
61+
ApiResponse<Void> postFcmToken(@AuthenticationPrincipal CustomUserDetails user, @Valid @RequestBody MemberReqDTO.PostFcmToken dto);
6062
}
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,53 @@
11
package com.example.scoi.domain.member.dto;
22

33
import com.example.scoi.domain.member.enums.ExchangeType;
4-
import jakarta.validation.constraints.Pattern;
4+
import jakarta.validation.constraints.NotBlank;
5+
import jakarta.validation.constraints.NotNull;
56

67
public class MemberReqDTO {
78

89
// 간편 비밀번호 변경
910
public record ChangePassword(
11+
@NotNull(message = "기존 간편 비밀번호는 필수입니다.")
12+
@NotBlank(message = "기존 간편 비밀번호는 빈칸일 수 없습니다.")
1013
String oldPassword,
14+
@NotNull(message = "신규 간편 비밀번호는 필수입니다.")
15+
@NotBlank(message = "신규 간편 비밀번호는 빈칸일 수 없습니다.")
1116
String newPassword
1217
){}
1318

1419
// 간편 비밀번호 재설정
1520
public record ResetPassword(
16-
@Pattern(regexp = "^\\d{11}$")
17-
String phoneNumber,
18-
String verificationToken,
21+
@NotNull(message = "SMS 인증 토큰은 필수입니다.")
22+
@NotBlank(message = "SMS 인증 토큰은 빈칸일 수 없습니다.")
23+
String verificationCode,
24+
@NotNull(message = "신규 간편 비밀번호는 필수입니다.")
25+
@NotBlank(message = "신규 간편 비밀번호는 빈칸일 수 없습니다.")
1926
String newPassword
2027
){}
2128

2229
// API키 등록 및 수정
2330
public record PostPatchApiKey(
31+
@NotNull(message = "거래소 타입은 빈칸일 수 없습니다.")
2432
ExchangeType exchangeType,
33+
@NotNull(message = "거래소 퍼블릭 키는 필수입니다.")
34+
@NotBlank(message = "거래소 퍼블릭 키는 빈칸일 수 없습니다.")
2535
String publicKey,
36+
@NotNull(message = "거래소 시크릿 키는 필수입니다.")
37+
@NotBlank(message = "거래소 시크릿 키는 빈칸일 수 없습니다.")
2638
String secretKey
2739
){}
2840

2941
// API키 삭제
3042
public record DeleteApiKey(
43+
@NotNull(message = "거래소 타입은 빈칸일 수 없습니다.")
3144
ExchangeType exchangeType
3245
){}
3346

3447
// FCM 토큰 등록
3548
public record PostFcmToken(
49+
@NotNull(message = "FCM 토큰은 필수입니다.")
50+
@NotBlank(message = "FCM 토큰은 빈칸일 수 없습니다.")
3651
String token
3752
){}
3853
}

src/main/java/com/example/scoi/global/apiPayload/handler/GeneralExceptionAdvice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public ResponseEntity<ApiResponse<?>> handleHttpMessageNotReadableException(
161161
);
162162
return ResponseEntity.status(GeneralErrorCode.JSON_PARSE_FAIL.getStatus()).body(errorResponse);
163163
} else if (ex.getMessage().contains("JSON parse error:")){
164-
log.warn("[ ]: Request Body 파싱에 실패했습니다.");
164+
log.warn("[ HttpMessageNotReadableException ]: Request Body 파싱에 실패했습니다.");
165165

166166
ApiResponse<Void> errorResponse = ApiResponse.onFailure(
167167
GeneralErrorCode.JSON_PARSE_FAIL,

0 commit comments

Comments
 (0)