From 782f0c170e38a1e2594fe50b267ada86dbde2532 Mon Sep 17 00:00:00 2001 From: hjoo <92681117+yhj1129@users.noreply.github.com> Date: Thu, 6 Apr 2023 13:58:30 +0900 Subject: [PATCH 01/27] Create README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..ec33808 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +[] +[] 연관관계에 대한 상세한 설정하기 (목차 4 참고) +[] JPA가 기본으로 제공하지 않는 쿼리에 대해서 Repository 테스트 코드를 작성하시오. +[] Controller에서 통합테스트를 작성하시오. +[] ER-Diagram을 만드시오. +[] Login 할때마다 로그 테이블에 기록을 남기시오. +[] Error 발생시에 로그 테이블에 기록을 남기시오. (로그인 하지 않은 상태에서는 로그를 남기지 마세요) +[] AOP를 꼭 한 군데는 적용하시오. (본인이 필요하다고 느끼는 곳) +[] 본인만의 어노테이션을 꼭 만들고, 꼭 한군데는 적용하시오. (본인이 필요하다고 느끼는 곳) +[] 어떠한 예외도 ResponseDto로 캐치하여 응답하시오. +[] 어떠한 정상적인 응답도 ResponseDto에 담아서 응답하시오. +[] 유효성 검사는 필수입니다. (null 여부와 공백 여부만 체크하세요) +[] 테이블 구조는 개인 취향에 따라 변경해도 되지만, 목차 2번의 기능은 다 완성해야 함. +[] 모든 기능을 완성하시오 (목차 2 참고) From df13fff69a638a527dfdfbf2a3e6ce1ebb8e799b Mon Sep 17 00:00:00 2001 From: hjoo <92681117+yhj1129@users.noreply.github.com> Date: Thu, 6 Apr 2023 13:58:55 +0900 Subject: [PATCH 02/27] Update README.md --- README.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/README.md b/README.md index ec33808..8b13789 100644 --- a/README.md +++ b/README.md @@ -1,14 +1 @@ -[] -[] 연관관계에 대한 상세한 설정하기 (목차 4 참고) -[] JPA가 기본으로 제공하지 않는 쿼리에 대해서 Repository 테스트 코드를 작성하시오. -[] Controller에서 통합테스트를 작성하시오. -[] ER-Diagram을 만드시오. -[] Login 할때마다 로그 테이블에 기록을 남기시오. -[] Error 발생시에 로그 테이블에 기록을 남기시오. (로그인 하지 않은 상태에서는 로그를 남기지 마세요) -[] AOP를 꼭 한 군데는 적용하시오. (본인이 필요하다고 느끼는 곳) -[] 본인만의 어노테이션을 꼭 만들고, 꼭 한군데는 적용하시오. (본인이 필요하다고 느끼는 곳) -[] 어떠한 예외도 ResponseDto로 캐치하여 응답하시오. -[] 어떠한 정상적인 응답도 ResponseDto에 담아서 응답하시오. -[] 유효성 검사는 필수입니다. (null 여부와 공백 여부만 체크하세요) -[] 테이블 구조는 개인 취향에 따라 변경해도 되지만, 목차 2번의 기능은 다 완성해야 함. -[] 모든 기능을 완성하시오 (목차 2 참고) + From 94a403fbdb1e2e6c75bc49ca0681df3397d0805f Mon Sep 17 00:00:00 2001 From: HJoo Date: Thu, 6 Apr 2023 14:14:28 +0900 Subject: [PATCH 03/27] =?UTF-8?q?[0]=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/shop/mtcoding/metamall/model/log/error/ErrorLog.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java b/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java index fbfe7e5..638cf90 100644 --- a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java +++ b/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java @@ -19,7 +19,6 @@ public class ErrorLog { private Long id; private String msg; private Long userId; - private LocalDateTime createdAt; private LocalDateTime updatedAt; From a8721ef4007529bec9aa0e2bb44493b19fea2ef6 Mon Sep 17 00:00:00 2001 From: HJoo Date: Thu, 6 Apr 2023 14:20:16 +0900 Subject: [PATCH 04/27] =?UTF-8?q?[0]=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/shop/mtcoding/metamall/model/log/error/ErrorLog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java b/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java index 638cf90..b999eb0 100644 --- a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java +++ b/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java @@ -18,6 +18,7 @@ public class ErrorLog { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String msg; + private Long userId; private LocalDateTime createdAt; private LocalDateTime updatedAt; From 08b4d25f89b412f4ff048bec7299b16f4f774d3a Mon Sep 17 00:00:00 2001 From: HJoo Date: Thu, 6 Apr 2023 15:17:22 +0900 Subject: [PATCH 05/27] =?UTF-8?q?[1]=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/mtcoding/metamall/MetamallApplication.java | 3 ++- .../mtcoding/metamall/controller/UserController.java | 10 ++++++++++ .../shop/mtcoding/metamall/core/jwt/JwtProvider.java | 2 +- .../mtcoding/metamall/model/log/login/LoginLog.java | 6 ------ .../java/shop/mtcoding/metamall/model/user/Role.java | 5 +++++ .../java/shop/mtcoding/metamall/model/user/User.java | 9 +++++++-- 6 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 src/main/java/shop/mtcoding/metamall/model/user/Role.java diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index 487bb62..a40c883 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -9,6 +9,7 @@ import shop.mtcoding.metamall.model.ordersheet.OrderSheet; import shop.mtcoding.metamall.model.ordersheet.OrderSheetRepository; import shop.mtcoding.metamall.model.product.ProductRepository; +import shop.mtcoding.metamall.model.user.Role; import shop.mtcoding.metamall.model.user.User; import shop.mtcoding.metamall.model.user.UserRepository; @@ -20,7 +21,7 @@ CommandLineRunner initData(UserRepository userRepository, ProductRepository prod return (args)->{ // 여기에서 save 하면 됨. // bulk Collector는 saveAll 하면 됨. - User ssar = User.builder().username("ssar").password("1234").email("ssar@nate.com").role("USER").build(); + User ssar = User.builder().username("ssar").password("1234").email("ssar@nate.com").role(Role.USER).build(); userRepository.save(ssar); }; } diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index ddfee94..2dcffd7 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -11,6 +11,7 @@ import shop.mtcoding.metamall.dto.user.UserResponse; import shop.mtcoding.metamall.model.log.login.LoginLog; import shop.mtcoding.metamall.model.log.login.LoginLogRepository; +import shop.mtcoding.metamall.model.user.Role; import shop.mtcoding.metamall.model.user.User; import shop.mtcoding.metamall.model.user.UserRepository; @@ -60,4 +61,13 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS throw new Exception400("유저네임 혹은 아이디가 잘못되었습니다"); } } + + @PostMapping("/join") + public ResponseEntity join(@RequestBody User joinUser){ + joinUser.setRole(Role.USER); + userRepository.save(joinUser); + System.out.println("UserController : join 호출됨 "); + ResponseDto responseDto = new ResponseDto<>().data(joinUser); + return ResponseEntity.ok().body(responseDto); + } } diff --git a/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java b/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java index 93a4bae..b314137 100644 --- a/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java +++ b/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java @@ -24,7 +24,7 @@ public static String create(User user) { .withSubject(SUBJECT) .withExpiresAt(new Date(System.currentTimeMillis() + EXP)) .withClaim("id", user.getId()) - .withClaim("role", user.getRole()) + .withClaim("role", user.getRole().toString()) .sign(Algorithm.HMAC512(SECRET)); System.out.println("디버그 : 토큰 생성됨"); return TOKEN_PREFIX + jwt; diff --git a/src/main/java/shop/mtcoding/metamall/model/log/login/LoginLog.java b/src/main/java/shop/mtcoding/metamall/model/log/login/LoginLog.java index 40b2964..245b2c1 100644 --- a/src/main/java/shop/mtcoding/metamall/model/log/login/LoginLog.java +++ b/src/main/java/shop/mtcoding/metamall/model/log/login/LoginLog.java @@ -21,18 +21,12 @@ public class LoginLog { private String userAgent; private String clientIP; private LocalDateTime createdAt; - private LocalDateTime updatedAt; @PrePersist protected void onCreate() { this.createdAt = LocalDateTime.now(); } - @PreUpdate - protected void onUpdate() { - this.updatedAt = LocalDateTime.now(); - } - @Builder public LoginLog(Long id, Long userId, String userAgent, String clientIP, LocalDateTime createdAt) { diff --git a/src/main/java/shop/mtcoding/metamall/model/user/Role.java b/src/main/java/shop/mtcoding/metamall/model/user/Role.java new file mode 100644 index 0000000..e607047 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/model/user/Role.java @@ -0,0 +1,5 @@ +package shop.mtcoding.metamall.model.user; + +public enum Role { + USER, SELLER, ADMIN +} diff --git a/src/main/java/shop/mtcoding/metamall/model/user/User.java b/src/main/java/shop/mtcoding/metamall/model/user/User.java index c929ce5..b40121d 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/User.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/User.java @@ -4,8 +4,10 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; import javax.persistence.*; +import java.sql.Timestamp; import java.time.LocalDateTime; @NoArgsConstructor @@ -17,10 +19,13 @@ public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(nullable = false, length = 30) private String username; + @Column(nullable = false, length = 100) private String password; + @Column(nullable = false, length = 50) private String email; - private String role; // USER(고객), SELLER(판매자), ADMIN(관리자) + private Role role; // USER(고객), SELLER(판매자), ADMIN(관리자) private LocalDateTime createdAt; private LocalDateTime updatedAt; @@ -35,7 +40,7 @@ protected void onUpdate() { } @Builder - public User(Long id, String username, String password, String email, String role, LocalDateTime createdAt) { + public User(Long id, String username, String password, String email, Role role, LocalDateTime createdAt) { this.id = id; this.username = username; this.password = password; From 3a0699dd543b159e2d8f2327eb648eec67cbd3e1 Mon Sep 17 00:00:00 2001 From: HJoo Date: Thu, 6 Apr 2023 17:38:12 +0900 Subject: [PATCH 06/27] temp --- .../metamall/MetamallApplication.java | 7 ++ .../controller/ProductController.java | 77 +++++++++++++++++++ .../metamall/controller/UserController.java | 7 +- .../metamall/core/jwt/JwtProvider.java | 2 +- .../metamall/dto/board/ProductRequest.java | 11 +++ .../metamall/dto/board/UserResponse.java | 6 ++ .../model/product/ProductRepository.java | 7 ++ .../mtcoding/metamall/model/user/User.java | 3 +- 8 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 src/main/java/shop/mtcoding/metamall/controller/ProductController.java create mode 100644 src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java create mode 100644 src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index a40c883..a2ad18a 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -8,11 +8,14 @@ import shop.mtcoding.metamall.model.orderproduct.OrderProductRepository; import shop.mtcoding.metamall.model.ordersheet.OrderSheet; import shop.mtcoding.metamall.model.ordersheet.OrderSheetRepository; +import shop.mtcoding.metamall.model.product.Product; import shop.mtcoding.metamall.model.product.ProductRepository; import shop.mtcoding.metamall.model.user.Role; import shop.mtcoding.metamall.model.user.User; import shop.mtcoding.metamall.model.user.UserRepository; +import java.time.LocalDateTime; + @SpringBootApplication public class MetamallApplication { @@ -21,8 +24,12 @@ CommandLineRunner initData(UserRepository userRepository, ProductRepository prod return (args)->{ // 여기에서 save 하면 됨. // bulk Collector는 saveAll 하면 됨. + User ssar = User.builder().username("ssar").password("1234").email("ssar@nate.com").role(Role.USER).build(); userRepository.save(ssar); + + Product prt = Product.builder().name("book").price(10000).qty(1).build(); + productRepository.save(prt); }; } diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java new file mode 100644 index 0000000..9a41b7f --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -0,0 +1,77 @@ +package shop.mtcoding.metamall.controller; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.interfaces.DecodedJWT; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import shop.mtcoding.metamall.core.exception.Exception400; +import shop.mtcoding.metamall.core.exception.Exception401; +import shop.mtcoding.metamall.core.jwt.JwtProvider; +import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.dto.board.ProductRequest; +import shop.mtcoding.metamall.dto.user.UserRequest; +import shop.mtcoding.metamall.model.log.login.LoginLog; +import shop.mtcoding.metamall.model.log.login.LoginLogRepository; +import shop.mtcoding.metamall.model.product.Product; +import shop.mtcoding.metamall.model.product.ProductRepository; +import shop.mtcoding.metamall.model.user.Role; +import shop.mtcoding.metamall.model.user.User; +import shop.mtcoding.metamall.model.user.UserRepository; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.time.LocalDateTime; +import java.util.Optional; + +@RequiredArgsConstructor +@RestController +public class ProductController { + + private final ProductRepository productRepository; + private final HttpSession session; + + @GetMapping("/find") + public ResponseEntity login(@RequestBody ProductRequest.ProductDto productDto, HttpServletRequest request) { + + //인증만 필요 + String jwt = request.getHeader(JwtProvider.HEADER).replace("Bearer ", ""); + System.out.println(jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + Optional productOP = productRepository.findByName(productDto.getName()); + if (productOP.isPresent()) { + // 1. 물건 정보 꺼내기 + Product findProduct = productOP.get(); + + // 2. 응답 DTO 생성 + ResponseDto responseDto = new ResponseDto<>().data(findProduct); + return ResponseEntity.ok().body(responseDto); + } else { + throw new Exception400("잘못된 요청입니다"); + } + } + + @PostMapping("/upload") + public ResponseEntity upload(@RequestBody Product uploadProduct){ + try { + // 1. 사용자의 토큰 인증 + String jwt = (String) session.getAttribute(JwtProvider.HEADER); + DecodedJWT decode = JwtProvider.verify(jwt); + + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decode.getClaim("role").asString(); + if(role.equals(Role.SELLER)){ + productRepository.save(uploadProduct); + System.out.println("ProductController : upload 호출됨 "); + ResponseDto responseDto = new ResponseDto<>().data(uploadProduct); + return ResponseEntity.ok().body(responseDto); + }else{ + throw new Exception400("판매자만 등록할 수 있습니다"); + } + }catch (Exception e){ + throw new Exception400("잘못된 요청입니다"); + } + } +} diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index 2dcffd7..b1faa01 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -42,7 +42,7 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS // 3. JWT 생성하기 String jwt = JwtProvider.create(userOP.get()); - + System.out.println(jwt); // 4. 최종 로그인 날짜 기록 (더티체킹 - update 쿼리 발생) loginUser.setUpdatedAt(LocalDateTime.now()); @@ -54,6 +54,11 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS .build(); loginLogRepository.save(loginLog); + String authHeader = request.getHeader(JwtProvider.HEADER); + if (authHeader != null) { + request.removeAttribute("Authorization"); + } + // 6. 응답 DTO 생성 ResponseDto responseDto = new ResponseDto<>().data(loginUser); return ResponseEntity.ok().header(JwtProvider.HEADER, jwt).body(responseDto); diff --git a/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java b/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java index b314137..e863fde 100644 --- a/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java +++ b/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java @@ -14,7 +14,7 @@ public class JwtProvider { private static final String SUBJECT = "jwtstudy"; - private static final int EXP = 1000 * 60 * 60; + private static final int EXP = 1000 * 60 * 60 * 24 * 100; public static final String TOKEN_PREFIX = "Bearer "; // 스페이스 필요함 public static final String HEADER = "Authorization"; private static final String SECRET = "메타코딩"; diff --git a/src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java b/src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java new file mode 100644 index 0000000..cfe7480 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java @@ -0,0 +1,11 @@ +package shop.mtcoding.metamall.dto.board; + +import lombok.Getter; +import lombok.Setter; + +public class ProductRequest { + @Getter @Setter + public static class ProductDto { + private String name; + } +} diff --git a/src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java b/src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java new file mode 100644 index 0000000..9f9edab --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java @@ -0,0 +1,6 @@ +package shop.mtcoding.metamall.dto.board; + +// 응답 DTO는 서비스 배우고 나서 하기 (할 수 있으면 해보기) +public class UserResponse { + +} diff --git a/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java b/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java index ba5def3..42d1eb4 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java @@ -1,6 +1,13 @@ package shop.mtcoding.metamall.model.product; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import shop.mtcoding.metamall.model.user.User; + +import java.util.Optional; public interface ProductRepository extends JpaRepository { + @Query("select p from Product p where p.name = :name") + Optional findByName(@Param("name") String name); } diff --git a/src/main/java/shop/mtcoding/metamall/model/user/User.java b/src/main/java/shop/mtcoding/metamall/model/user/User.java index b40121d..327ecd4 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/User.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/User.java @@ -40,12 +40,13 @@ protected void onUpdate() { } @Builder - public User(Long id, String username, String password, String email, Role role, LocalDateTime createdAt) { + public User(Long id, String username, String password, String email, Role role, LocalDateTime createdAt, LocalDateTime updatedAt) { this.id = id; this.username = username; this.password = password; this.email = email; this.role = role; this.createdAt = createdAt; + this.updatedAt = updatedAt; } } From 54e5817a4f4798c510f5f9667f3f59d580c58ee1 Mon Sep 17 00:00:00 2001 From: HJoo Date: Thu, 6 Apr 2023 20:21:06 +0900 Subject: [PATCH 07/27] =?UTF-8?q?[2]=20=EB=AC=BC=EA=B1=B4=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D/=EC=A0=84=EC=B2=B4=EC=A1=B0=ED=9A=8C/=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/MetamallApplication.java | 2 + .../controller/ProductController.java | 72 ++++++++++--------- .../metamall/controller/UserController.java | 9 +-- .../metamall/core/jwt/JwtProvider.java | 2 +- .../{board => product}/ProductRequest.java | 2 +- .../dto/{board => product}/UserResponse.java | 2 +- .../metamall/dto/user/UserResponse.java | 6 -- .../metamall/model/product/Product.java | 3 + .../mtcoding/metamall/model/user/Role.java | 2 +- .../mtcoding/metamall/model/user/User.java | 1 - 10 files changed, 49 insertions(+), 52 deletions(-) rename src/main/java/shop/mtcoding/metamall/dto/{board => product}/ProductRequest.java (79%) rename src/main/java/shop/mtcoding/metamall/dto/{board => product}/UserResponse.java (71%) delete mode 100644 src/main/java/shop/mtcoding/metamall/dto/user/UserResponse.java diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index a2ad18a..11f4e60 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -24,6 +24,8 @@ CommandLineRunner initData(UserRepository userRepository, ProductRepository prod return (args)->{ // 여기에서 save 하면 됨. // bulk Collector는 saveAll 하면 됨. + User seller = User.builder().username("seller").password("1234").email("seller@nate.com").role(Role.SELLER).build(); + userRepository.save(seller); User ssar = User.builder().username("ssar").password("1234").email("ssar@nate.com").role(Role.USER).build(); userRepository.save(ssar); diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java index 9a41b7f..7270632 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -1,28 +1,20 @@ package shop.mtcoding.metamall.controller; -import com.auth0.jwt.JWT; -import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import shop.mtcoding.metamall.core.exception.Exception400; -import shop.mtcoding.metamall.core.exception.Exception401; import shop.mtcoding.metamall.core.jwt.JwtProvider; import shop.mtcoding.metamall.dto.ResponseDto; -import shop.mtcoding.metamall.dto.board.ProductRequest; -import shop.mtcoding.metamall.dto.user.UserRequest; -import shop.mtcoding.metamall.model.log.login.LoginLog; -import shop.mtcoding.metamall.model.log.login.LoginLogRepository; +import shop.mtcoding.metamall.dto.product.ProductRequest; import shop.mtcoding.metamall.model.product.Product; import shop.mtcoding.metamall.model.product.ProductRepository; import shop.mtcoding.metamall.model.user.Role; -import shop.mtcoding.metamall.model.user.User; -import shop.mtcoding.metamall.model.user.UserRepository; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; @RequiredArgsConstructor @@ -33,14 +25,14 @@ public class ProductController { private final HttpSession session; @GetMapping("/find") - public ResponseEntity login(@RequestBody ProductRequest.ProductDto productDto, HttpServletRequest request) { - + public ResponseEntity find(@RequestBody ProductRequest.ProductDto product, HttpServletRequest request) { + System.out.println("ProductController : find 호출됨 "); //인증만 필요 - String jwt = request.getHeader(JwtProvider.HEADER).replace("Bearer ", ""); - System.out.println(jwt); - DecodedJWT decodedJWT = JwtProvider.verify(jwt); + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); - Optional productOP = productRepository.findByName(productDto.getName()); + Optional productOP = productRepository.findByName(product.getName()); if (productOP.isPresent()) { // 1. 물건 정보 꺼내기 Product findProduct = productOP.get(); @@ -53,25 +45,37 @@ public ResponseEntity login(@RequestBody ProductRequest.ProductDto productDto } } + @GetMapping("/findAll") + public ResponseEntity findAll(HttpServletRequest request) { + System.out.println("ProductController : findAll 호출됨 "); + //인증만 필요 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + List productOP = productRepository.findAll(); + ResponseDto responseDto = new ResponseDto<>().data(productOP); + return ResponseEntity.ok().body(responseDto); + } + @PostMapping("/upload") - public ResponseEntity upload(@RequestBody Product uploadProduct){ - try { - // 1. 사용자의 토큰 인증 - String jwt = (String) session.getAttribute(JwtProvider.HEADER); - DecodedJWT decode = JwtProvider.verify(jwt); + public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletRequest request){ + System.out.println("ProductController : upload 호출됨 "); + // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 - String role = decode.getClaim("role").asString(); - if(role.equals(Role.SELLER)){ - productRepository.save(uploadProduct); - System.out.println("ProductController : upload 호출됨 "); - ResponseDto responseDto = new ResponseDto<>().data(uploadProduct); - return ResponseEntity.ok().body(responseDto); - }else{ - throw new Exception400("판매자만 등록할 수 있습니다"); - } - }catch (Exception e){ - throw new Exception400("잘못된 요청입니다"); - } + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decodedJWT.getClaim("role").asString(); + System.out.println("Role : " + role); + if(role.equals(Role.SELLER.toString())){ + productRepository.save(uploadProduct); + System.out.println("권한 확인 완료"); + ResponseDto responseDto = new ResponseDto<>().data(uploadProduct); + return ResponseEntity.ok().body(responseDto); + }else{ + throw new Exception400("판매자만 등록할 수 있습니다"); + } } } diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index b1faa01..69be1e1 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -8,7 +8,6 @@ import shop.mtcoding.metamall.core.jwt.JwtProvider; import shop.mtcoding.metamall.dto.ResponseDto; import shop.mtcoding.metamall.dto.user.UserRequest; -import shop.mtcoding.metamall.dto.user.UserResponse; import shop.mtcoding.metamall.model.log.login.LoginLog; import shop.mtcoding.metamall.model.log.login.LoginLogRepository; import shop.mtcoding.metamall.model.user.Role; @@ -30,6 +29,7 @@ public class UserController { @PostMapping("/login") public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpServletRequest request) { + System.out.println("UserController : login 호출됨 "); Optional userOP = userRepository.findByUsername(loginDto.getUsername()); if (userOP.isPresent()) { // 1. 유저 정보 꺼내기 @@ -42,7 +42,7 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS // 3. JWT 생성하기 String jwt = JwtProvider.create(userOP.get()); - System.out.println(jwt); + System.out.println(jwt.replace("Bearer ", "")); // 4. 최종 로그인 날짜 기록 (더티체킹 - update 쿼리 발생) loginUser.setUpdatedAt(LocalDateTime.now()); @@ -54,11 +54,6 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS .build(); loginLogRepository.save(loginLog); - String authHeader = request.getHeader(JwtProvider.HEADER); - if (authHeader != null) { - request.removeAttribute("Authorization"); - } - // 6. 응답 DTO 생성 ResponseDto responseDto = new ResponseDto<>().data(loginUser); return ResponseEntity.ok().header(JwtProvider.HEADER, jwt).body(responseDto); diff --git a/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java b/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java index e863fde..b314137 100644 --- a/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java +++ b/src/main/java/shop/mtcoding/metamall/core/jwt/JwtProvider.java @@ -14,7 +14,7 @@ public class JwtProvider { private static final String SUBJECT = "jwtstudy"; - private static final int EXP = 1000 * 60 * 60 * 24 * 100; + private static final int EXP = 1000 * 60 * 60; public static final String TOKEN_PREFIX = "Bearer "; // 스페이스 필요함 public static final String HEADER = "Authorization"; private static final String SECRET = "메타코딩"; diff --git a/src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java b/src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java similarity index 79% rename from src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java rename to src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java index cfe7480..f25b376 100644 --- a/src/main/java/shop/mtcoding/metamall/dto/board/ProductRequest.java +++ b/src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java @@ -1,4 +1,4 @@ -package shop.mtcoding.metamall.dto.board; +package shop.mtcoding.metamall.dto.product; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java b/src/main/java/shop/mtcoding/metamall/dto/product/UserResponse.java similarity index 71% rename from src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java rename to src/main/java/shop/mtcoding/metamall/dto/product/UserResponse.java index 9f9edab..02b3dc7 100644 --- a/src/main/java/shop/mtcoding/metamall/dto/board/UserResponse.java +++ b/src/main/java/shop/mtcoding/metamall/dto/product/UserResponse.java @@ -1,4 +1,4 @@ -package shop.mtcoding.metamall.dto.board; +package shop.mtcoding.metamall.dto.product; // 응답 DTO는 서비스 배우고 나서 하기 (할 수 있으면 해보기) public class UserResponse { diff --git a/src/main/java/shop/mtcoding/metamall/dto/user/UserResponse.java b/src/main/java/shop/mtcoding/metamall/dto/user/UserResponse.java deleted file mode 100644 index ae218ec..0000000 --- a/src/main/java/shop/mtcoding/metamall/dto/user/UserResponse.java +++ /dev/null @@ -1,6 +0,0 @@ -package shop.mtcoding.metamall.dto.user; - -// 응답 DTO는 서비스 배우고 나서 하기 (할 수 있으면 해보기) -public class UserResponse { - -} diff --git a/src/main/java/shop/mtcoding/metamall/model/product/Product.java b/src/main/java/shop/mtcoding/metamall/model/product/Product.java index bc8c618..dcfe475 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/Product.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/Product.java @@ -17,8 +17,11 @@ public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(nullable = false, length = 50) private String name; // 상품 이름 + @Column(nullable = false, length = Integer.MAX_VALUE) private Integer price; // 상품 가격 + @Column(nullable = false, length = Integer.MAX_VALUE) private Integer qty; // 상품 재고 private LocalDateTime createdAt; private LocalDateTime updatedAt; diff --git a/src/main/java/shop/mtcoding/metamall/model/user/Role.java b/src/main/java/shop/mtcoding/metamall/model/user/Role.java index e607047..34b765c 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/Role.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/Role.java @@ -1,5 +1,5 @@ package shop.mtcoding.metamall.model.user; public enum Role { - USER, SELLER, ADMIN + USER,SELLER,ADMIN } diff --git a/src/main/java/shop/mtcoding/metamall/model/user/User.java b/src/main/java/shop/mtcoding/metamall/model/user/User.java index 327ecd4..d8d3ddb 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/User.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/User.java @@ -47,6 +47,5 @@ public User(Long id, String username, String password, String email, Role role, this.email = email; this.role = role; this.createdAt = createdAt; - this.updatedAt = updatedAt; } } From 02a9da4e45dede36d72178205f6c6e037dea9bea Mon Sep 17 00:00:00 2001 From: HJoo Date: Fri, 7 Apr 2023 17:08:03 +0900 Subject: [PATCH 08/27] =?UTF-8?q?[3]=20=EB=AC=BC=EA=B1=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95(=EA=B0=80=EA=B2=A9=EA=B3=BC=20=EC=88=98=EB=9F=89)/?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/MetamallApplication.java | 7 ++- .../controller/ProductController.java | 62 +++++++++++++++++++ .../model/product/ProductRepository.java | 1 - 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index 11f4e60..768463a 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -30,8 +30,11 @@ CommandLineRunner initData(UserRepository userRepository, ProductRepository prod User ssar = User.builder().username("ssar").password("1234").email("ssar@nate.com").role(Role.USER).build(); userRepository.save(ssar); - Product prt = Product.builder().name("book").price(10000).qty(1).build(); - productRepository.save(prt); + Product book = Product.builder().name("book1").price(10000).qty(100).build(); + productRepository.save(book); + + Product book2 = Product.builder().name("book2").price(15000).qty(100).build(); + productRepository.save(book2); }; } diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java index 7270632..827348c 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -3,6 +3,7 @@ import com.auth0.jwt.interfaces.DecodedJWT; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import shop.mtcoding.metamall.core.exception.Exception400; import shop.mtcoding.metamall.core.jwt.JwtProvider; @@ -78,4 +79,65 @@ public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletR throw new Exception400("판매자만 등록할 수 있습니다"); } } + + @Transactional + @PutMapping("/update/{bookname}") + public ResponseEntity update(@PathVariable String bookname, @RequestBody Product updateProduct, HttpServletRequest request){ + System.out.println("ProductController : update 호출됨 "); + // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt update : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decodedJWT.getClaim("role").asString(); + System.out.println("Role : " + role); + + if(role.equals(Role.SELLER.toString())){ + System.out.println("권한 확인 완료"); + + Product productPS = productRepository.findByName(bookname).orElseThrow(() -> { + return new Exception400("제품의 이름을 찾을 수 없습니다. "); + }); //영속화 하기 + + productPS.setPrice(updateProduct.getPrice()); + productPS.setQty(updateProduct.getQty()); + + ResponseDto responseDto = new ResponseDto<>().data(updateProduct); + return ResponseEntity.ok().body(responseDto); + + }else{ + throw new Exception400("판매자만 등록할 수 있습니다"); + } + } + + @Transactional + @DeleteMapping("/delete/{name}") + public ResponseEntity delete(@PathVariable String name, HttpServletRequest request){ + System.out.println("ProductController : delete 호출됨 "); + // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt delete : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decodedJWT.getClaim("role").asString(); + System.out.println("Role : " + role); + + if(role.equals(Role.SELLER.toString())){ + System.out.println("권한 확인 완료"); + + Product productPS = productRepository.findByName(name).orElseThrow(() -> { + return new Exception400("제품의 이름을 찾을 수 없습니다. "); + }); //제품이 있는지 확인 + + productRepository.deleteById(productPS.getId()); + + ResponseDto responseDto = new ResponseDto<>().data("Delete Success!"); + return ResponseEntity.ok().body(responseDto); + + }else{ + throw new Exception400("판매자만 삭제할 수 있습니다"); + } + } } diff --git a/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java b/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java index 42d1eb4..cfa4f1d 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java @@ -3,7 +3,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import shop.mtcoding.metamall.model.user.User; import java.util.Optional; From 9ef5684d444d202c21864ff37e64ad8ad7fdcbe3 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sat, 8 Apr 2023 12:02:36 +0900 Subject: [PATCH 09/27] =?UTF-8?q?[4]=20=EC=A3=BC=EB=AC=B8/=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=20=EB=AA=A9=EB=A1=9D=20=EB=B3=B4=EA=B8=B0(=EA=B3=A0?= =?UTF-8?q?=EA=B0=9D=EA=B3=BC=20=ED=8C=90=EB=A7=A4=EC=9E=90)=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/MetamallApplication.java | 2 + .../metamall/controller/OrderController.java | 192 ++++++++++++++++++ .../metamall/controller/UserController.java | 6 + .../metamall/dto/order/OrderRequest.java | 14 ++ .../model/orderproduct/OrderProduct.java | 21 +- .../metamall/model/ordersheet/OrderSheet.java | 4 +- .../ordersheet/OrderSheetRepository.java | 7 + 7 files changed, 236 insertions(+), 10 deletions(-) create mode 100644 src/main/java/shop/mtcoding/metamall/controller/OrderController.java create mode 100644 src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index 768463a..8e46739 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -29,6 +29,8 @@ CommandLineRunner initData(UserRepository userRepository, ProductRepository prod User ssar = User.builder().username("ssar").password("1234").email("ssar@nate.com").role(Role.USER).build(); userRepository.save(ssar); + OrderSheet orderSheet = OrderSheet.builder().user(ssar).totalPrice(0).build(); + orderSheetRepository.save(orderSheet); // 한 고객 당 주문 시트 생성 Product book = Product.builder().name("book1").price(10000).qty(100).build(); productRepository.save(book); diff --git a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java new file mode 100644 index 0000000..0fc35af --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java @@ -0,0 +1,192 @@ +package shop.mtcoding.metamall.controller; + +import com.auth0.jwt.interfaces.DecodedJWT; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import shop.mtcoding.metamall.core.exception.Exception400; +import shop.mtcoding.metamall.core.jwt.JwtProvider; +import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.dto.order.OrderRequest; +import shop.mtcoding.metamall.model.orderproduct.OrderProduct; +import shop.mtcoding.metamall.model.orderproduct.OrderProductRepository; +import shop.mtcoding.metamall.model.ordersheet.OrderSheet; +import shop.mtcoding.metamall.model.ordersheet.OrderSheetRepository; +import shop.mtcoding.metamall.model.product.Product; +import shop.mtcoding.metamall.model.product.ProductRepository; +import shop.mtcoding.metamall.model.user.Role; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.List; + +@RequiredArgsConstructor +@RestController +public class OrderController { + + private final ProductRepository productRepository; + private final HttpSession session; + private final OrderProductRepository orderProductRepository; + private final OrderSheetRepository orderSheetRepository; + + @PostMapping("/order") + @Transactional + public ResponseEntity order(@RequestBody OrderRequest.OrderDto orderDto, HttpServletRequest request) { + + System.out.println("OrderController : order 호출됨 "); + String name = orderDto.getName(); + Integer count = orderDto.getCount(); + + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + // 사용자의 권한 확인 USER + String role = decodedJWT.getClaim("role").asString(); + Long userId = decodedJWT.getClaim("id").asLong(); + System.out.println("Role : " + role); + System.out.println("userId : " + userId); + + if(role.equals(Role.USER.toString())){ //USER 여야 주문가능 + Product productPS = productRepository.findByName(name).orElseThrow(() -> { + return new Exception400("제품의 이름을 찾을 수 없습니다. "); + }); + + if(productPS.getQty() - count< 0){ + throw new Exception400("상품의 수량이 부족합니다. "); + } + productPS.setQty(productPS.getQty() - count); //수량 업데이트 + OrderProduct orderProduct = OrderProduct.builder().product(productPS).count(count).orderPrice(productPS.getPrice() * count).build(); + orderProductRepository.save(orderProduct); + + OrderSheet orderSheetPS = orderSheetRepository.findByUserId(userId).orElseThrow(() -> { // 주문서 찾기 + return new Exception400("잘못된 접근입니다. "); + }); + List orderProductList = orderSheetPS.getOrderProductList(); + orderProductList.add(orderProduct); + orderSheetPS.setOrderProductList(orderProductList); //orderProduct 추가된 리스트로 업데이트 + + + Integer totalPrice = orderSheetPS.getTotalPrice(); + totalPrice = totalPrice + orderProduct.getOrderPrice(); + orderSheetPS.setTotalPrice(totalPrice); + + orderProduct.setOrderSheet(orderSheetPS.getId()); + + System.out.println("권한 확인 완료"); + ResponseDto responseDto = new ResponseDto<>().data(orderSheetPS); + return ResponseEntity.ok().body(responseDto); + }else { + throw new Exception400("고객만 주문할 수 있습니다"); + } + } + + @GetMapping("/findAllOrder") + public ResponseEntity findAllOrder(HttpServletRequest request) { + System.out.println("OrderController : findAllOrder 호출됨 "); + // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decodedJWT.getClaim("role").asString(); + Long userId = decodedJWT.getClaim("id").asLong(); + + if(role.equals(Role.USER.toString())){ + OrderSheet orderSheet = orderSheetRepository.findByUserId(userId).get(); + List orderProductList = orderSheet.getOrderProductList(); + ResponseDto responseDto = new ResponseDto<>().data(orderProductList); + return ResponseEntity.ok().body(responseDto); + }else if(role.equals(Role.SELLER.toString())){ + List orderSheetList = orderSheetRepository.findAll(); + ResponseDto responseDto = new ResponseDto<>().data(orderSheetList); + return ResponseEntity.ok().body(responseDto); + }else { + throw new Exception400("고객만 주문 목록에 접근할 수 있습니다"); + } + } + +// @PostMapping("/upload") +// public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletRequest request){ +// System.out.println("ProductController : upload 호출됨 "); +// // 1. 사용자의 토큰 인증 +// String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); +// System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); +// DecodedJWT decodedJWT = JwtProvider.verify(jwt); +// +// // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 +// String role = decodedJWT.getClaim("role").asString(); +// System.out.println("Role : " + role); +// if(role.equals(Role.SELLER.toString())){ +// productRepository.save(uploadProduct); +// System.out.println("권한 확인 완료"); +// ResponseDto responseDto = new ResponseDto<>().data(uploadProduct); +// return ResponseEntity.ok().body(responseDto); +// }else{ +// throw new Exception400("판매자만 등록할 수 있습니다"); +// } +// } + +// @Transactional +// @PutMapping("/update/{bookname}") +// public ResponseEntity update(@PathVariable String bookname, @RequestBody Product updateProduct, HttpServletRequest request){ +// System.out.println("ProductController : update 호출됨 "); +// // 1. 사용자의 토큰 인증 +// String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); +// System.out.println( JwtProvider.HEADER + " - jwt update : " + jwt); +// DecodedJWT decodedJWT = JwtProvider.verify(jwt); +// +// // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 +// String role = decodedJWT.getClaim("role").asString(); +// System.out.println("Role : " + role); +// +// if(role.equals(Role.SELLER.toString())){ +// System.out.println("권한 확인 완료"); +// +// Product productPS = productRepository.findByName(bookname).orElseThrow(() -> { +// return new Exception400("제품의 이름을 찾을 수 없습니다. "); +// }); //영속화 하기 +// +// productPS.setPrice(updateProduct.getPrice()); +// productPS.setQty(updateProduct.getQty()); +// +// ResponseDto responseDto = new ResponseDto<>().data(updateProduct); +// return ResponseEntity.ok().body(responseDto); +// +// }else{ +// throw new Exception400("판매자만 등록할 수 있습니다"); +// } +// } +// +// @Transactional +// @DeleteMapping("/delete/{name}") +// public ResponseEntity delete(@PathVariable String name, HttpServletRequest request){ +// System.out.println("ProductController : delete 호출됨 "); +// // 1. 사용자의 토큰 인증 +// String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); +// System.out.println( JwtProvider.HEADER + " - jwt delete : " + jwt); +// DecodedJWT decodedJWT = JwtProvider.verify(jwt); +// +// // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 +// String role = decodedJWT.getClaim("role").asString(); +// System.out.println("Role : " + role); +// +// if(role.equals(Role.SELLER.toString())){ +// System.out.println("권한 확인 완료"); +// +// Product productPS = productRepository.findByName(name).orElseThrow(() -> { +// return new Exception400("제품의 이름을 찾을 수 없습니다. "); +// }); //제품이 있는지 확인 +// +// productRepository.deleteById(productPS.getId()); +// +// ResponseDto responseDto = new ResponseDto<>().data("Delete Success!"); +// return ResponseEntity.ok().body(responseDto); +// +// }else{ +// throw new Exception400("판매자만 삭제할 수 있습니다"); +// } +// } +} diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index 69be1e1..6da6032 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -10,6 +10,8 @@ import shop.mtcoding.metamall.dto.user.UserRequest; import shop.mtcoding.metamall.model.log.login.LoginLog; import shop.mtcoding.metamall.model.log.login.LoginLogRepository; +import shop.mtcoding.metamall.model.ordersheet.OrderSheet; +import shop.mtcoding.metamall.model.ordersheet.OrderSheetRepository; import shop.mtcoding.metamall.model.user.Role; import shop.mtcoding.metamall.model.user.User; import shop.mtcoding.metamall.model.user.UserRepository; @@ -25,6 +27,7 @@ public class UserController { private final UserRepository userRepository; private final LoginLogRepository loginLogRepository; + private final OrderSheetRepository orderSheetRepository; private final HttpSession session; @PostMapping("/login") @@ -67,6 +70,9 @@ public ResponseEntity join(@RequestBody User joinUser){ joinUser.setRole(Role.USER); userRepository.save(joinUser); System.out.println("UserController : join 호출됨 "); + OrderSheet orderSheet = OrderSheet.builder().user(joinUser).totalPrice(0).build(); + orderSheetRepository.save(orderSheet); // 한 고객 당 주문 시트 생성 + ResponseDto responseDto = new ResponseDto<>().data(joinUser); return ResponseEntity.ok().body(responseDto); } diff --git a/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java b/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java new file mode 100644 index 0000000..5671429 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java @@ -0,0 +1,14 @@ +package shop.mtcoding.metamall.dto.order; + +import lombok.Getter; +import lombok.Setter; +import shop.mtcoding.metamall.model.product.Product; +import shop.mtcoding.metamall.model.user.User; + +public class OrderRequest { + @Getter @Setter + public static class OrderDto { + private String name; + private Integer count; + } +} diff --git a/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java b/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java index 165905e..c5226ec 100644 --- a/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java +++ b/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java @@ -20,33 +20,36 @@ public class OrderProduct { // 주문 상품 @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne + @JoinColumn(name = "productId") private Product product; + @Column(nullable = false) private Integer count; // 상품 주문 개수 private Integer orderPrice; // 상품 주문 금액 private LocalDateTime createdAt; - private LocalDateTime updatedAt; +// private LocalDateTime updatedAt; - @ManyToOne - private OrderSheet orderSheet; +// @ManyToOne +// OrderSheet를 저장하고 싶었는데 어려워서 일단 id로 + private Long orderSheet; @PrePersist protected void onCreate() { this.createdAt = LocalDateTime.now(); } - @PreUpdate - protected void onUpdate() { - this.updatedAt = LocalDateTime.now(); - } +// @PreUpdate 업데이트가 필요 있나? +// protected void onUpdate() { +// this.updatedAt = LocalDateTime.now(); +// } @Builder - public OrderProduct(Long id, Product product, Integer count, Integer orderPrice, LocalDateTime createdAt, LocalDateTime updatedAt, OrderSheet orderSheet) { + public OrderProduct(Long id, Product product, Integer count, Integer orderPrice, LocalDateTime createdAt, Long orderSheet) { this.id = id; this.product = product; this.count = count; this.orderPrice = orderPrice; this.createdAt = createdAt; - this.updatedAt = updatedAt; +// this.updatedAt = updatedAt; this.orderSheet = orderSheet; } } diff --git a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java index 7638710..241eff2 100644 --- a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java +++ b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java @@ -23,8 +23,10 @@ public class OrderSheet { // 주문서 @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne + @JoinColumn(name = "userId") private User user; // 주문자 - @OneToMany(mappedBy = "orderSheet") + + @OneToMany(mappedBy = "orderSheet", fetch = FetchType.LAZY) private List orderProductList = new ArrayList<>(); // 총 주문 상품 리스트 private Integer totalPrice; // 총 주문 금액 (총 주문 상품 리스트의 orderPrice 합) private LocalDateTime createdAt; diff --git a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java index 5d59249..866f98a 100644 --- a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java @@ -1,6 +1,13 @@ package shop.mtcoding.metamall.model.ordersheet; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import shop.mtcoding.metamall.model.product.Product; + +import java.util.Optional; public interface OrderSheetRepository extends JpaRepository { + @Query("select o from OrderSheet o where o.user.id = :userId") + Optional findByUserId(@Param("userId") Long userId); } From cd13097b750de3337cf73b9fade5bb0aa6a30ef2 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sat, 8 Apr 2023 12:52:15 +0900 Subject: [PATCH 10/27] =?UTF-8?q?[5]=20=EC=A3=BC=EB=AC=B8=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C(=EA=B3=A0=EA=B0=9D/=ED=8C=90=EB=A7=A4=EC=9E=90=20?= =?UTF-8?q?=EA=B8=B0=EC=A4=80)=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/controller/OrderController.java | 138 +++++++----------- .../metamall/model/ordersheet/OrderSheet.java | 2 +- .../ordersheet/OrderSheetRepository.java | 7 + .../metamall/model/user/UserRepository.java | 2 +- 4 files changed, 64 insertions(+), 85 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java index 0fc35af..3743448 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java @@ -16,10 +16,13 @@ import shop.mtcoding.metamall.model.product.Product; import shop.mtcoding.metamall.model.product.ProductRepository; import shop.mtcoding.metamall.model.user.Role; +import shop.mtcoding.metamall.model.user.User; +import shop.mtcoding.metamall.model.user.UserRepository; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.List; +import java.util.Optional; @RequiredArgsConstructor @RestController @@ -29,6 +32,7 @@ public class OrderController { private final HttpSession session; private final OrderProductRepository orderProductRepository; private final OrderSheetRepository orderSheetRepository; + private final UserRepository userRepository; @PostMapping("/order") @Transactional @@ -94,12 +98,12 @@ public ResponseEntity findAllOrder(HttpServletRequest request) { String role = decodedJWT.getClaim("role").asString(); Long userId = decodedJWT.getClaim("id").asLong(); - if(role.equals(Role.USER.toString())){ + if(role.equals(Role.USER.toString())){ // 고객일 경우 본인의 주문 목록 보기 OrderSheet orderSheet = orderSheetRepository.findByUserId(userId).get(); List orderProductList = orderSheet.getOrderProductList(); ResponseDto responseDto = new ResponseDto<>().data(orderProductList); return ResponseEntity.ok().body(responseDto); - }else if(role.equals(Role.SELLER.toString())){ + }else if(role.equals(Role.SELLER.toString())){ // 판매자일 경우 모든 주문 목록 보기 List orderSheetList = orderSheetRepository.findAll(); ResponseDto responseDto = new ResponseDto<>().data(orderSheetList); return ResponseEntity.ok().body(responseDto); @@ -108,85 +112,53 @@ public ResponseEntity findAllOrder(HttpServletRequest request) { } } -// @PostMapping("/upload") -// public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletRequest request){ -// System.out.println("ProductController : upload 호출됨 "); -// // 1. 사용자의 토큰 인증 -// String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); -// System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); -// DecodedJWT decodedJWT = JwtProvider.verify(jwt); -// -// // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 -// String role = decodedJWT.getClaim("role").asString(); -// System.out.println("Role : " + role); -// if(role.equals(Role.SELLER.toString())){ -// productRepository.save(uploadProduct); -// System.out.println("권한 확인 완료"); -// ResponseDto responseDto = new ResponseDto<>().data(uploadProduct); -// return ResponseEntity.ok().body(responseDto); -// }else{ -// throw new Exception400("판매자만 등록할 수 있습니다"); -// } -// } - -// @Transactional -// @PutMapping("/update/{bookname}") -// public ResponseEntity update(@PathVariable String bookname, @RequestBody Product updateProduct, HttpServletRequest request){ -// System.out.println("ProductController : update 호출됨 "); -// // 1. 사용자의 토큰 인증 -// String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); -// System.out.println( JwtProvider.HEADER + " - jwt update : " + jwt); -// DecodedJWT decodedJWT = JwtProvider.verify(jwt); -// -// // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 -// String role = decodedJWT.getClaim("role").asString(); -// System.out.println("Role : " + role); -// -// if(role.equals(Role.SELLER.toString())){ -// System.out.println("권한 확인 완료"); -// -// Product productPS = productRepository.findByName(bookname).orElseThrow(() -> { -// return new Exception400("제품의 이름을 찾을 수 없습니다. "); -// }); //영속화 하기 -// -// productPS.setPrice(updateProduct.getPrice()); -// productPS.setQty(updateProduct.getQty()); -// -// ResponseDto responseDto = new ResponseDto<>().data(updateProduct); -// return ResponseEntity.ok().body(responseDto); -// -// }else{ -// throw new Exception400("판매자만 등록할 수 있습니다"); -// } -// } -// -// @Transactional -// @DeleteMapping("/delete/{name}") -// public ResponseEntity delete(@PathVariable String name, HttpServletRequest request){ -// System.out.println("ProductController : delete 호출됨 "); -// // 1. 사용자의 토큰 인증 -// String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); -// System.out.println( JwtProvider.HEADER + " - jwt delete : " + jwt); -// DecodedJWT decodedJWT = JwtProvider.verify(jwt); -// -// // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 -// String role = decodedJWT.getClaim("role").asString(); -// System.out.println("Role : " + role); -// -// if(role.equals(Role.SELLER.toString())){ -// System.out.println("권한 확인 완료"); -// -// Product productPS = productRepository.findByName(name).orElseThrow(() -> { -// return new Exception400("제품의 이름을 찾을 수 없습니다. "); -// }); //제품이 있는지 확인 -// -// productRepository.deleteById(productPS.getId()); -// -// ResponseDto responseDto = new ResponseDto<>().data("Delete Success!"); -// return ResponseEntity.ok().body(responseDto); -// -// }else{ -// throw new Exception400("판매자만 삭제할 수 있습니다"); -// } -// } + @DeleteMapping("/cancel") + public ResponseEntity cancel(HttpServletRequest request){ + System.out.println("OrderController : cancel 호출됨 "); + // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decodedJWT.getClaim("role").asString(); + Long userId = decodedJWT.getClaim("id").asLong(); + + if(role.equals(Role.USER.toString())) { // 고객일 경우 본인의 주문 목록 삭제하기 -> 빈 주문 목록으로 새로 생성해주기 + orderSheetRepository.deleteByUserId(userId); + Optional user = userRepository.findById(userId); + OrderSheet orderSheet = OrderSheet.builder().user(user.get()).totalPrice(0).build(); + orderSheetRepository.save(orderSheet); + ResponseDto responseDto = new ResponseDto<>().data("주문이 정상적으로 취소되었습니다. "); + return ResponseEntity.ok().body(responseDto); + }else { + throw new Exception400("잘못된 접근입니다. "); + } + } + + @DeleteMapping("/cancel/{userId}") + public ResponseEntity cancelSeller(@PathVariable Long userId, HttpServletRequest request){ + System.out.println("OrderController : cancelSeller 호출됨 "); + // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + String role = decodedJWT.getClaim("role").asString(); + + if(role.equals(Role.SELLER.toString())){ // 판매자일 경우 본인의 body에 입력한 고객의 주문 목록 삭제하기 -> 빈 주문 목록으로 새로 생성해주기 + // Long userId = Long.parseLong(id); + orderSheetRepository.deleteByUserId(userId); + User user = userRepository.findById(userId).orElseThrow(() -> { + return new Exception400(userId + "번 고객을 찾을 수 없습니다. "); + }); + OrderSheet orderSheet = OrderSheet.builder().user(user).totalPrice(0).build(); + orderSheetRepository.save(orderSheet); + ResponseDto responseDto = new ResponseDto<>().data(userId + "번 고객의 주문이 정상적으로 취소되었습니다. "); + return ResponseEntity.ok().body(responseDto); + }else { + throw new Exception400("잘못된 접근입니다. "); + } + } } diff --git a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java index 241eff2..8c5a322 100644 --- a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java +++ b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java @@ -26,7 +26,7 @@ public class OrderSheet { // 주문서 @JoinColumn(name = "userId") private User user; // 주문자 - @OneToMany(mappedBy = "orderSheet", fetch = FetchType.LAZY) + @OneToMany(mappedBy = "orderSheet", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)// OrderSheet를 삭제하면 OrderProduct 들도 사라지게 private List orderProductList = new ArrayList<>(); // 총 주문 상품 리스트 private Integer totalPrice; // 총 주문 금액 (총 주문 상품 리스트의 orderPrice 합) private LocalDateTime createdAt; diff --git a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java index 866f98a..a391ff5 100644 --- a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java @@ -1,8 +1,10 @@ package shop.mtcoding.metamall.model.ordersheet; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; import shop.mtcoding.metamall.model.product.Product; import java.util.Optional; @@ -10,4 +12,9 @@ public interface OrderSheetRepository extends JpaRepository { @Query("select o from OrderSheet o where o.user.id = :userId") Optional findByUserId(@Param("userId") Long userId); + + @Modifying + @Transactional + @Query("delete from OrderSheet o where o.user.id = :userId") + void deleteByUserId(@Param("userId") Long userId); } diff --git a/src/main/java/shop/mtcoding/metamall/model/user/UserRepository.java b/src/main/java/shop/mtcoding/metamall/model/user/UserRepository.java index 293a101..2f642f9 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/UserRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/UserRepository.java @@ -6,7 +6,7 @@ import java.util.Optional; -public interface UserRepository extends JpaRepository { +public interface UserRepository extends JpaRepository { @Query("select u from User u where u.username = :username") Optional findByUsername(@Param("username") String username); From 113dbc88bc0da2b89e72d7717800cbd173f1ae35 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sat, 8 Apr 2023 18:07:13 +0900 Subject: [PATCH 11/27] =?UTF-8?q?[6]=20=EC=9D=91=EB=8B=B5=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=BD=94=EB=93=9C=20=EC=83=81=EC=84=B8=ED=9E=88=20?= =?UTF-8?q?=EC=A7=80=EC=A0=95=20/=20=20=EB=A1=9C=EA=B7=B8=EC=97=90=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/MetamallApplication.java | 4 +- .../metamall/controller/OrderController.java | 58 +++++++++---------- .../controller/ProductController.java | 50 +++++++--------- .../metamall/controller/UserController.java | 25 +++++--- .../core/advice/MyExceptionAdvice.java | 47 ++++++++++++--- .../metamall/core/exception/Exception400.java | 6 ++ .../metamall/core/exception/Exception401.java | 2 + .../metamall/core/exception/Exception403.java | 5 ++ .../metamall/core/exception/Exception404.java | 3 + .../metamall/core/exception/Exception500.java | 3 + .../metamall/core/filter/JwtVerifyFilter.java | 5 +- .../metamall/core/session/LoginUser.java | 5 +- .../model/log/{error => err}/ErrorLog.java | 17 +++--- .../model/log/err/ErrorLogRepository.java | 9 +++ .../model/log/error/ErrorLogRepository.java | 6 -- 15 files changed, 147 insertions(+), 98 deletions(-) rename src/main/java/shop/mtcoding/metamall/model/log/{error => err}/ErrorLog.java (72%) create mode 100644 src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLogRepository.java delete mode 100644 src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLogRepository.java diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index 8e46739..e8e2e26 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -4,6 +4,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; +import shop.mtcoding.metamall.model.log.login.LoginLogRepository; import shop.mtcoding.metamall.model.orderproduct.OrderProduct; import shop.mtcoding.metamall.model.orderproduct.OrderProductRepository; import shop.mtcoding.metamall.model.ordersheet.OrderSheet; @@ -20,7 +22,7 @@ public class MetamallApplication { @Bean - CommandLineRunner initData(UserRepository userRepository, ProductRepository productRepository, OrderProductRepository orderProductRepository, OrderSheetRepository orderSheetRepository){ + CommandLineRunner initData(UserRepository userRepository, ProductRepository productRepository, OrderProductRepository orderProductRepository, OrderSheetRepository orderSheetRepository, ErrorLogRepository errorLogRepository, LoginLogRepository loginLogRepository){ return (args)->{ // 여기에서 save 하면 됨. // bulk Collector는 saveAll 하면 됨. diff --git a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java index 3743448..ed359a9 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java @@ -6,6 +6,9 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import shop.mtcoding.metamall.core.exception.Exception400; +import shop.mtcoding.metamall.core.exception.Exception401; +import shop.mtcoding.metamall.core.exception.Exception403; +import shop.mtcoding.metamall.core.exception.Exception404; import shop.mtcoding.metamall.core.jwt.JwtProvider; import shop.mtcoding.metamall.dto.ResponseDto; import shop.mtcoding.metamall.dto.order.OrderRequest; @@ -38,89 +41,80 @@ public class OrderController { @Transactional public ResponseEntity order(@RequestBody OrderRequest.OrderDto orderDto, HttpServletRequest request) { - System.out.println("OrderController : order 호출됨 "); - String name = orderDto.getName(); - Integer count = orderDto.getCount(); - String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); + String name = orderDto.getName(); + Integer count = orderDto.getCount(); + // 사용자의 권한 확인 USER String role = decodedJWT.getClaim("role").asString(); Long userId = decodedJWT.getClaim("id").asLong(); - System.out.println("Role : " + role); - System.out.println("userId : " + userId); + if(role.equals(Role.USER.toString())){ //USER 여야 주문가능 Product productPS = productRepository.findByName(name).orElseThrow(() -> { - return new Exception400("제품의 이름을 찾을 수 없습니다. "); + return new Exception404("제품의 이름을 찾을 수 없습니다. "); }); if(productPS.getQty() - count< 0){ - throw new Exception400("상품의 수량이 부족합니다. "); + throw new Exception400("제품의 수량이 부족합니다. "); } productPS.setQty(productPS.getQty() - count); //수량 업데이트 OrderProduct orderProduct = OrderProduct.builder().product(productPS).count(count).orderPrice(productPS.getPrice() * count).build(); orderProductRepository.save(orderProduct); - OrderSheet orderSheetPS = orderSheetRepository.findByUserId(userId).orElseThrow(() -> { // 주문서 찾기 - return new Exception400("잘못된 접근입니다. "); - }); + OrderSheet orderSheetPS = orderSheetRepository.findByUserId(userId).get(); List orderProductList = orderSheetPS.getOrderProductList(); orderProductList.add(orderProduct); orderSheetPS.setOrderProductList(orderProductList); //orderProduct 추가된 리스트로 업데이트 - Integer totalPrice = orderSheetPS.getTotalPrice(); totalPrice = totalPrice + orderProduct.getOrderPrice(); orderSheetPS.setTotalPrice(totalPrice); orderProduct.setOrderSheet(orderSheetPS.getId()); - System.out.println("권한 확인 완료"); ResponseDto responseDto = new ResponseDto<>().data(orderSheetPS); return ResponseEntity.ok().body(responseDto); }else { - throw new Exception400("고객만 주문할 수 있습니다"); + throw new Exception403("잘못된 접근입니다. "); } } @GetMapping("/findAllOrder") public ResponseEntity findAllOrder(HttpServletRequest request) { - System.out.println("OrderController : findAllOrder 호출됨 "); - // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + // 사용자의 권한 확인 String role = decodedJWT.getClaim("role").asString(); - Long userId = decodedJWT.getClaim("id").asLong(); + Long userId = decodedJWT.getClaim("id").asLong(); if(role.equals(Role.USER.toString())){ // 고객일 경우 본인의 주문 목록 보기 OrderSheet orderSheet = orderSheetRepository.findByUserId(userId).get(); List orderProductList = orderSheet.getOrderProductList(); ResponseDto responseDto = new ResponseDto<>().data(orderProductList); return ResponseEntity.ok().body(responseDto); + }else if(role.equals(Role.SELLER.toString())){ // 판매자일 경우 모든 주문 목록 보기 List orderSheetList = orderSheetRepository.findAll(); ResponseDto responseDto = new ResponseDto<>().data(orderSheetList); return ResponseEntity.ok().body(responseDto); + }else { - throw new Exception400("고객만 주문 목록에 접근할 수 있습니다"); + throw new Exception401("인증되지 않은 고객입니다."); } } @DeleteMapping("/cancel") public ResponseEntity cancel(HttpServletRequest request){ - System.out.println("OrderController : cancel 호출됨 "); - // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + // 2. 사용자의 권한 확인 String role = decodedJWT.getClaim("role").asString(); Long userId = decodedJWT.getClaim("id").asLong(); @@ -132,33 +126,33 @@ public ResponseEntity cancel(HttpServletRequest request){ ResponseDto responseDto = new ResponseDto<>().data("주문이 정상적으로 취소되었습니다. "); return ResponseEntity.ok().body(responseDto); }else { - throw new Exception400("잘못된 접근입니다. "); + throw new Exception403("잘못된 접근입니다. "); } } @DeleteMapping("/cancel/{userId}") public ResponseEntity cancelSeller(@PathVariable Long userId, HttpServletRequest request){ - System.out.println("OrderController : cancelSeller 호출됨 "); - // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + // 사용자의 권한 확인 SELLER(판매자) String role = decodedJWT.getClaim("role").asString(); + Long id = decodedJWT.getClaim("id").asLong(); if(role.equals(Role.SELLER.toString())){ // 판매자일 경우 본인의 body에 입력한 고객의 주문 목록 삭제하기 -> 빈 주문 목록으로 새로 생성해주기 // Long userId = Long.parseLong(id); orderSheetRepository.deleteByUserId(userId); User user = userRepository.findById(userId).orElseThrow(() -> { - return new Exception400(userId + "번 고객을 찾을 수 없습니다. "); + return new Exception404(userId + "번 고객을 찾을 수 없습니다. "); }); OrderSheet orderSheet = OrderSheet.builder().user(user).totalPrice(0).build(); orderSheetRepository.save(orderSheet); + ResponseDto responseDto = new ResponseDto<>().data(userId + "번 고객의 주문이 정상적으로 취소되었습니다. "); return ResponseEntity.ok().body(responseDto); }else { - throw new Exception400("잘못된 접근입니다. "); + throw new Exception403("잘못된 접근입니다. "); } } } diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java index 827348c..da146ba 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -6,6 +6,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import shop.mtcoding.metamall.core.exception.Exception400; +import shop.mtcoding.metamall.core.exception.Exception403; import shop.mtcoding.metamall.core.jwt.JwtProvider; import shop.mtcoding.metamall.dto.ResponseDto; import shop.mtcoding.metamall.dto.product.ProductRequest; @@ -27,12 +28,12 @@ public class ProductController { @GetMapping("/find") public ResponseEntity find(@RequestBody ProductRequest.ProductDto product, HttpServletRequest request) { - System.out.println("ProductController : find 호출됨 "); //인증만 필요 String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); + Long userId = decodedJWT.getClaim("id").asLong(); + Optional productOP = productRepository.findByName(product.getName()); if (productOP.isPresent()) { // 1. 물건 정보 꺼내기 @@ -48,10 +49,7 @@ public ResponseEntity find(@RequestBody ProductRequest.ProductDto product, Ht @GetMapping("/findAll") public ResponseEntity findAll(HttpServletRequest request) { - System.out.println("ProductController : findAll 호출됨 "); - //인증만 필요 String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); List productOP = productRepository.findAll(); @@ -61,42 +59,38 @@ public ResponseEntity findAll(HttpServletRequest request) { @PostMapping("/upload") public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletRequest request){ - System.out.println("ProductController : upload 호출됨 "); - // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt upload : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + Long userId = decodedJWT.getClaim("id").asLong(); + + // 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 String role = decodedJWT.getClaim("role").asString(); - System.out.println("Role : " + role); + if(role.equals(Role.SELLER.toString())){ productRepository.save(uploadProduct); - System.out.println("권한 확인 완료"); ResponseDto responseDto = new ResponseDto<>().data(uploadProduct); return ResponseEntity.ok().body(responseDto); }else{ - throw new Exception400("판매자만 등록할 수 있습니다"); + throw new Exception403("판매자만 물건을 등록할 수 있습니다"); } } @Transactional - @PutMapping("/update/{bookname}") - public ResponseEntity update(@PathVariable String bookname, @RequestBody Product updateProduct, HttpServletRequest request){ - System.out.println("ProductController : update 호출됨 "); - // 1. 사용자의 토큰 인증 + @PutMapping("/update/{productname}") + public ResponseEntity update(@PathVariable String productname, @RequestBody Product updateProduct, HttpServletRequest request){ + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt update : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + // 사용자의 권한 확인 SELLER(판매자) String role = decodedJWT.getClaim("role").asString(); - System.out.println("Role : " + role); + Long userId = decodedJWT.getClaim("id").asLong(); if(role.equals(Role.SELLER.toString())){ - System.out.println("권한 확인 완료"); - Product productPS = productRepository.findByName(bookname).orElseThrow(() -> { + Product productPS = productRepository.findByName(productname).orElseThrow(() -> { return new Exception400("제품의 이름을 찾을 수 없습니다. "); }); //영속화 하기 @@ -107,26 +101,22 @@ public ResponseEntity update(@PathVariable String bookname, @RequestBody Prod return ResponseEntity.ok().body(responseDto); }else{ - throw new Exception400("판매자만 등록할 수 있습니다"); + throw new Exception403("잘못된 접근입니다. "); } } @Transactional @DeleteMapping("/delete/{name}") public ResponseEntity delete(@PathVariable String name, HttpServletRequest request){ - System.out.println("ProductController : delete 호출됨 "); - // 1. 사용자의 토큰 인증 + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); - System.out.println( JwtProvider.HEADER + " - jwt delete : " + jwt); DecodedJWT decodedJWT = JwtProvider.verify(jwt); + Long userId = decodedJWT.getClaim("id").asLong(); - // 2. 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + // 사용자의 권한 확인 SELLER(판매자) String role = decodedJWT.getClaim("role").asString(); - System.out.println("Role : " + role); if(role.equals(Role.SELLER.toString())){ - System.out.println("권한 확인 완료"); - Product productPS = productRepository.findByName(name).orElseThrow(() -> { return new Exception400("제품의 이름을 찾을 수 없습니다. "); }); //제품이 있는지 확인 @@ -137,7 +127,7 @@ public ResponseEntity delete(@PathVariable String name, HttpServletRequest re return ResponseEntity.ok().body(responseDto); }else{ - throw new Exception400("판매자만 삭제할 수 있습니다"); + throw new Exception403("잘못된 접근입니다. "); } } } diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index 6da6032..89b4ed8 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -3,9 +3,11 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import shop.mtcoding.metamall.core.anotation.Authorize; import shop.mtcoding.metamall.core.exception.Exception400; import shop.mtcoding.metamall.core.exception.Exception401; import shop.mtcoding.metamall.core.jwt.JwtProvider; +import shop.mtcoding.metamall.core.session.LoginUser; import shop.mtcoding.metamall.dto.ResponseDto; import shop.mtcoding.metamall.dto.user.UserRequest; import shop.mtcoding.metamall.model.log.login.LoginLog; @@ -28,37 +30,43 @@ public class UserController { private final UserRepository userRepository; private final LoginLogRepository loginLogRepository; private final OrderSheetRepository orderSheetRepository; + private final HttpSession session; @PostMapping("/login") public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpServletRequest request) { - System.out.println("UserController : login 호출됨 "); + session.setAttribute("login", null); Optional userOP = userRepository.findByUsername(loginDto.getUsername()); if (userOP.isPresent()) { // 1. 유저 정보 꺼내기 - User loginUser = userOP.get(); + User user = userOP.get(); // 2. 패스워드 검증하기 - if(!loginUser.getPassword().equals(loginDto.getPassword())){ + if(!user.getPassword().equals(loginDto.getPassword())){ throw new Exception401("인증되지 않았습니다"); } // 3. JWT 생성하기 String jwt = JwtProvider.create(userOP.get()); - System.out.println(jwt.replace("Bearer ", "")); + // 4. 최종 로그인 날짜 기록 (더티체킹 - update 쿼리 발생) - loginUser.setUpdatedAt(LocalDateTime.now()); + user.setUpdatedAt(LocalDateTime.now()); // 5. 로그 테이블 기록 LoginLog loginLog = LoginLog.builder() - .userId(loginUser.getId()) + .userId(user.getId()) .userAgent(request.getHeader("User-Agent")) .clientIP(request.getRemoteAddr()) .build(); loginLogRepository.save(loginLog); - // 6. 응답 DTO 생성 - ResponseDto responseDto = new ResponseDto<>().data(loginUser); +// 6. loginUser에 저장 - 에러에 사용하기 위해서 + LoginUser loginUser = LoginUser.builder().id(user.getId()).role(user.getRole().toString()).build(); + session.setAttribute("login", loginUser); + System.out.println("로그인 후 유저 정보 : " + loginUser); + + // 7. 응답 DTO 생성 + ResponseDto responseDto = new ResponseDto<>().data(user); return ResponseEntity.ok().header(JwtProvider.HEADER, jwt).body(responseDto); } else { throw new Exception400("유저네임 혹은 아이디가 잘못되었습니다"); @@ -69,7 +77,6 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS public ResponseEntity join(@RequestBody User joinUser){ joinUser.setRole(Role.USER); userRepository.save(joinUser); - System.out.println("UserController : join 호출됨 "); OrderSheet orderSheet = OrderSheet.builder().user(joinUser).totalPrice(0).build(); orderSheetRepository.save(orderSheet); // 한 고객 당 주문 시트 생성 diff --git a/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java b/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java index 50ebee2..831c363 100644 --- a/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java +++ b/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java @@ -3,10 +3,15 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import shop.mtcoding.metamall.core.exception.*; -import shop.mtcoding.metamall.model.log.error.ErrorLogRepository; +import shop.mtcoding.metamall.core.session.LoginUser; +import shop.mtcoding.metamall.model.log.err.ErrorLog; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; + +import javax.servlet.http.HttpSession; @Slf4j @RequiredArgsConstructor @@ -15,28 +20,56 @@ public class MyExceptionAdvice { private final ErrorLogRepository errorLogRepository; + private final HttpSession session; + @ExceptionHandler(Exception400.class) - public ResponseEntity badRequest(Exception400 e){ + public ResponseEntity badRequest(Exception400 e) { // 잘못된 요청을 했을 때 + LoginUser loginUser = (LoginUser) session.getAttribute("login"); + if (loginUser != null) { //로그인이 되었을 때 + ErrorLog errorLog = ErrorLog.builder().userId(loginUser.getId()).msg("code : 400 - " + e.getMessage()).build(); + errorLogRepository.save(errorLog); + } return new ResponseEntity<>(e.body(), e.status()); } @ExceptionHandler(Exception401.class) - public ResponseEntity unAuthorized(Exception401 e){ + public ResponseEntity unAuthorized(Exception401 e) { // 인증되지 않았을 때 + LoginUser loginUser = (LoginUser) session.getAttribute("login"); + if (loginUser != null) { //로그인이 되었을 때 + ErrorLog errorLog = ErrorLog.builder().userId(loginUser.getId()).msg("code : 401 - " + e.getMessage()).build(); + errorLogRepository.save(errorLog); + } return new ResponseEntity<>(e.body(), e.status()); } @ExceptionHandler(Exception403.class) - public ResponseEntity forbidden(Exception403 e){ + public ResponseEntity forbidden(Exception403 e) { // 사용자가 잘못된 접근을 했을 때 + LoginUser loginUser = (LoginUser) session.getAttribute("login"); + System.out.println("에러 발생 유저 : " + loginUser); + if (loginUser != null) { //로그인이 되었을 때 + ErrorLog errorLog = ErrorLog.builder().userId(loginUser.getId()).msg("code : 403 - " + e.getMessage()).build(); + errorLogRepository.save(errorLog); + } return new ResponseEntity<>(e.body(), e.status()); } @ExceptionHandler(Exception404.class) - public ResponseEntity notFound(Exception404 e){ + public ResponseEntity notFound(Exception404 e) { // 객체를 찾을 수 없을 때 + LoginUser loginUser = (LoginUser) session.getAttribute("login"); + if (loginUser != null) { //로그인이 되었을 때 + ErrorLog errorLog = ErrorLog.builder().userId(loginUser.getId()).msg("code : 404 - " + e.getMessage()).build(); + errorLogRepository.save(errorLog); + } return new ResponseEntity<>(e.body(), e.status()); } @ExceptionHandler(Exception500.class) - public ResponseEntity serverError(Exception500 e){ + public ResponseEntity serverError(Exception500 e) { + LoginUser loginUser = (LoginUser) session.getAttribute("login"); + if (loginUser != null) { //로그인이 되었을 때 + ErrorLog errorLog = ErrorLog.builder().userId(loginUser.getId()).msg("code : 500 - " + e.getMessage()).build(); + errorLogRepository.save(errorLog); + } return new ResponseEntity<>(e.body(), e.status()); } -} +} \ No newline at end of file diff --git a/src/main/java/shop/mtcoding/metamall/core/exception/Exception400.java b/src/main/java/shop/mtcoding/metamall/core/exception/Exception400.java index d1b5fec..f99856b 100644 --- a/src/main/java/shop/mtcoding/metamall/core/exception/Exception400.java +++ b/src/main/java/shop/mtcoding/metamall/core/exception/Exception400.java @@ -1,13 +1,19 @@ package shop.mtcoding.metamall.core.exception; import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; + + import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.model.log.err.ErrorLog; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; // 유효성 실패 @Getter public class Exception400 extends RuntimeException { + public Exception400(String message) { super(message); } diff --git a/src/main/java/shop/mtcoding/metamall/core/exception/Exception401.java b/src/main/java/shop/mtcoding/metamall/core/exception/Exception401.java index 5d2f310..0c79bf7 100644 --- a/src/main/java/shop/mtcoding/metamall/core/exception/Exception401.java +++ b/src/main/java/shop/mtcoding/metamall/core/exception/Exception401.java @@ -4,6 +4,8 @@ import lombok.Getter; import org.springframework.http.HttpStatus; import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.model.log.err.ErrorLog; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; // 인증 안됨 diff --git a/src/main/java/shop/mtcoding/metamall/core/exception/Exception403.java b/src/main/java/shop/mtcoding/metamall/core/exception/Exception403.java index c8dc137..562ae9d 100644 --- a/src/main/java/shop/mtcoding/metamall/core/exception/Exception403.java +++ b/src/main/java/shop/mtcoding/metamall/core/exception/Exception403.java @@ -1,13 +1,18 @@ package shop.mtcoding.metamall.core.exception; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.model.log.err.ErrorLog; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; // 권한 없음 @Getter public class Exception403 extends RuntimeException { + public Exception403(String message) { super(message); } diff --git a/src/main/java/shop/mtcoding/metamall/core/exception/Exception404.java b/src/main/java/shop/mtcoding/metamall/core/exception/Exception404.java index c20b64f..e883d72 100644 --- a/src/main/java/shop/mtcoding/metamall/core/exception/Exception404.java +++ b/src/main/java/shop/mtcoding/metamall/core/exception/Exception404.java @@ -3,6 +3,8 @@ import lombok.Getter; import org.springframework.http.HttpStatus; import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.model.log.err.ErrorLog; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; // 리소스 없음 @@ -10,6 +12,7 @@ public class Exception404 extends RuntimeException { public Exception404(String message) { super(message); + } public ResponseDto body(){ diff --git a/src/main/java/shop/mtcoding/metamall/core/exception/Exception500.java b/src/main/java/shop/mtcoding/metamall/core/exception/Exception500.java index d3d4468..ec6e4fb 100644 --- a/src/main/java/shop/mtcoding/metamall/core/exception/Exception500.java +++ b/src/main/java/shop/mtcoding/metamall/core/exception/Exception500.java @@ -3,11 +3,14 @@ import lombok.Getter; import org.springframework.http.HttpStatus; import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.model.log.err.ErrorLog; +import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; // 서버 에러 @Getter public class Exception500 extends RuntimeException { + public Exception500(String message) { super(message); } diff --git a/src/main/java/shop/mtcoding/metamall/core/filter/JwtVerifyFilter.java b/src/main/java/shop/mtcoding/metamall/core/filter/JwtVerifyFilter.java index 870bf93..347dd7a 100644 --- a/src/main/java/shop/mtcoding/metamall/core/filter/JwtVerifyFilter.java +++ b/src/main/java/shop/mtcoding/metamall/core/filter/JwtVerifyFilter.java @@ -10,6 +10,7 @@ import shop.mtcoding.metamall.core.jwt.JwtProvider; import shop.mtcoding.metamall.core.session.LoginUser; import shop.mtcoding.metamall.dto.ResponseDto; +import shop.mtcoding.metamall.model.user.Role; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; @@ -31,8 +32,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha String jwt = prefixJwt.replace(JwtProvider.TOKEN_PREFIX, ""); try { DecodedJWT decodedJWT = JwtProvider.verify(jwt); - int id = decodedJWT.getClaim("id").asInt(); - String role = decodedJWT.getClaim("role").asString(); + Long id = decodedJWT.getClaim("id").asLong(); + String role = decodedJWT.getClaim("role").toString(); // 세션을 사용하는 이유는 권한처리를 하기 위해서이다. HttpSession session = req.getSession(); diff --git a/src/main/java/shop/mtcoding/metamall/core/session/LoginUser.java b/src/main/java/shop/mtcoding/metamall/core/session/LoginUser.java index 59f402c..d8a63ea 100644 --- a/src/main/java/shop/mtcoding/metamall/core/session/LoginUser.java +++ b/src/main/java/shop/mtcoding/metamall/core/session/LoginUser.java @@ -2,14 +2,15 @@ import lombok.Builder; import lombok.Getter; +import shop.mtcoding.metamall.model.user.Role; @Getter public class LoginUser { - private Integer id; + private Long id; private String role; @Builder - public LoginUser(Integer id, String role) { + public LoginUser(Long id, String role) { this.id = id; this.role = role; } diff --git a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java b/src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLog.java similarity index 72% rename from src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java rename to src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLog.java index b999eb0..5e2b195 100644 --- a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLog.java +++ b/src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLog.java @@ -1,4 +1,4 @@ -package shop.mtcoding.metamall.model.log.error; +package shop.mtcoding.metamall.model.log.err; import lombok.Builder; import lombok.Getter; @@ -18,27 +18,26 @@ public class ErrorLog { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String msg; - private Long userId; private LocalDateTime createdAt; - private LocalDateTime updatedAt; +// private LocalDateTime updatedAt; 필요 없을 듯 @PrePersist protected void onCreate() { this.createdAt = LocalDateTime.now(); } - @PreUpdate - protected void onUpdate() { - this.updatedAt = LocalDateTime.now(); - } +// @PreUpdate +// protected void onUpdate() { +// this.updatedAt = LocalDateTime.now(); +// } 필요 없을 듯 @Builder - public ErrorLog(Long id, String msg, Long userId, LocalDateTime createdAt, LocalDateTime updatedAt) { + public ErrorLog(Long id, String msg, Long userId, LocalDateTime createdAt) { this.id = id; this.msg = msg; this.userId = userId; this.createdAt = createdAt; - this.updatedAt = updatedAt; +// this.updatedAt = updatedAt; } } diff --git a/src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLogRepository.java b/src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLogRepository.java new file mode 100644 index 0000000..00bf732 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/model/log/err/ErrorLogRepository.java @@ -0,0 +1,9 @@ +package shop.mtcoding.metamall.model.log.err; + +import org.springframework.context.annotation.Bean; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; + +public interface ErrorLogRepository extends JpaRepository { +} diff --git a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLogRepository.java b/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLogRepository.java deleted file mode 100644 index 53c8a4f..0000000 --- a/src/main/java/shop/mtcoding/metamall/model/log/error/ErrorLogRepository.java +++ /dev/null @@ -1,6 +0,0 @@ -package shop.mtcoding.metamall.model.log.error; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ErrorLogRepository extends JpaRepository { -} From 6923f1a63636e26d02193cc2b482a291ebb3f1db Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 12:40:07 +0900 Subject: [PATCH 12/27] =?UTF-8?q?[7-1]=20=EA=B3=A0=EA=B0=9D=20=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mtcoding/metamall/model/user/User.java | 11 ++++++ .../model/user/UserRepositoryTest.java | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/test/java/shop/mtcoding/metamall/model/user/UserRepositoryTest.java diff --git a/src/main/java/shop/mtcoding/metamall/model/user/User.java b/src/main/java/shop/mtcoding/metamall/model/user/User.java index d8d3ddb..bd4a86b 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/User.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/User.java @@ -48,4 +48,15 @@ public User(Long id, String username, String password, String email, Role role, this.role = role; this.createdAt = createdAt; } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", email='" + email + '\'' + + ", role=" + role + + '}'; + } } diff --git a/src/test/java/shop/mtcoding/metamall/model/user/UserRepositoryTest.java b/src/test/java/shop/mtcoding/metamall/model/user/UserRepositoryTest.java new file mode 100644 index 0000000..eca9acb --- /dev/null +++ b/src/test/java/shop/mtcoding/metamall/model/user/UserRepositoryTest.java @@ -0,0 +1,35 @@ +package shop.mtcoding.metamall.model.user; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.jupiter.api.Assertions.*; + + +@RunWith(SpringRunner.class) +@DataJpaTest +class UserRepositoryTest { + + @Autowired + private UserRepository userRepository; + + + @Test + void findByUsername() { + //given + String username = "jju"; + User user = User.builder().username(username).email("nn").password("1234").build(); //userId = 3 + userRepository.save(user); + //when + User findUser = userRepository.findByUsername(username).get(); + //then + System.out.println("find================" + findUser); + Assertions.assertThat(findUser.getId()).isEqualTo(3); + + } +} \ No newline at end of file From 5c041ba571d580ac7842ce2b0354bb197ec2c53a Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 12:40:47 +0900 Subject: [PATCH 13/27] =?UTF-8?q?[7-2]=20=EC=83=81=ED=92=88=20=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/model/product/Product.java | 10 ++++++ .../model/product/ProductRepositoryTest.java | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java diff --git a/src/main/java/shop/mtcoding/metamall/model/product/Product.java b/src/main/java/shop/mtcoding/metamall/model/product/Product.java index dcfe475..b58762b 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/Product.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/Product.java @@ -45,4 +45,14 @@ public Product(Long id, String name, Integer price, Integer qty, LocalDateTime c this.createdAt = createdAt; this.updatedAt = updatedAt; } + + @Override + public String toString() { + return "Product{" + + "id=" + id + + ", name='" + name + '\'' + + ", price=" + price + + ", qty=" + qty + + '}'; + } } diff --git a/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java b/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java new file mode 100644 index 0000000..7557627 --- /dev/null +++ b/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java @@ -0,0 +1,33 @@ +package shop.mtcoding.metamall.model.product; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.jupiter.api.Assertions.*; + +@RunWith(SpringRunner.class) +@DataJpaTest +class ProductRepositoryTest { + + @Autowired + private ProductRepository productRepository; + + + @Test + void findByName() { + //given + String productname = "phone"; + Product product = Product.builder().name(productname).price(1000).qty(10).build(); // id : 3 + productRepository.save(product); + //when + Product findProduct = productRepository.findByName(productname).get(); + //then + System.out.println("find ============ " + findProduct); + Assertions.assertThat(findProduct.getId()).isEqualTo(3); + } +} \ No newline at end of file From dd44810c028d022d88b1b053511389a07a4cfdbf Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 13:08:08 +0900 Subject: [PATCH 14/27] =?UTF-8?q?[7-3]=20=EC=A3=BC=EB=AC=B8=EC=8B=9C?= =?UTF-8?q?=ED=8A=B8=20=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/model/ordersheet/OrderSheet.java | 10 ++++ .../ordersheet/OrderSheetRepository.java | 1 - .../ordersheet/OrderSheetRepositoryTest.java | 59 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/test/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepositoryTest.java diff --git a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java index 8c5a322..5e119cb 100644 --- a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java +++ b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheet.java @@ -52,4 +52,14 @@ public OrderSheet(Long id, User user, Integer totalPrice, LocalDateTime createdA this.createdAt = createdAt; this.updatedAt = updatedAt; } + + @Override + public String toString() { + return "OrderSheet{" + + "id=" + id + + ", user=" + user + + ", orderProductList=" + orderProductList + + ", totalPrice=" + totalPrice + + '}'; + } } diff --git a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java index a391ff5..e30be5e 100644 --- a/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepository.java @@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; -import shop.mtcoding.metamall.model.product.Product; import java.util.Optional; diff --git a/src/test/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepositoryTest.java b/src/test/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepositoryTest.java new file mode 100644 index 0000000..86b21e5 --- /dev/null +++ b/src/test/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepositoryTest.java @@ -0,0 +1,59 @@ +package shop.mtcoding.metamall.model.ordersheet; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; +import shop.mtcoding.metamall.model.user.Role; +import shop.mtcoding.metamall.model.user.User; +import shop.mtcoding.metamall.model.user.UserRepository; + +import java.util.Optional; + +@RunWith(SpringRunner.class) +@DataJpaTest +class OrderSheetRepositoryTest { + @Autowired + private OrderSheetRepository orderSheetRepository; + @Autowired + private UserRepository userRepository; + + @BeforeEach + void setUp() { + User user = User.builder().username("jju").email("nn").password("1234").build(); //userId = 3 + user.setRole(Role.USER); + userRepository.save(user); + OrderSheet orderSheet = OrderSheet.builder().user(user).totalPrice(0).build(); + orderSheetRepository.save(orderSheet); + } + + @Test + void findByUserId() { + //given + Long userId = 3L; + + //when + Optional orderSheetOP = orderSheetRepository.findByUserId(userId); + + //then + String username = orderSheetOP.get().getUser().getUsername(); + Assertions.assertThat(username).isEqualTo("jju"); + } + + @Test + void deleteByUserId() { + //given + Long userId = 2L; + + //when + orderSheetRepository.deleteByUserId(userId); + + //then + + Assertions.assertThat(orderSheetRepository.findByUserId(userId)).isNotPresent(); + } +} \ No newline at end of file From b675e469a3d13402893cabbdf9e9c7db43807f93 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 15:04:05 +0900 Subject: [PATCH 15/27] =?UTF-8?q?[8-1]=20=EA=B3=A0=EA=B0=9D=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metamall/controller/UserController.java | 2 +- .../controller/UserControllerTest.java | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index 89b4ed8..f3e7535 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -63,7 +63,7 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS // 6. loginUser에 저장 - 에러에 사용하기 위해서 LoginUser loginUser = LoginUser.builder().id(user.getId()).role(user.getRole().toString()).build(); session.setAttribute("login", loginUser); - System.out.println("로그인 후 유저 정보 : " + loginUser); + System.out.println("로그인 후 유저 정보 : " + loginUser.toString()); // 7. 응답 DTO 생성 ResponseDto responseDto = new ResponseDto<>().data(user); diff --git a/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java new file mode 100644 index 0000000..5bd24c4 --- /dev/null +++ b/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java @@ -0,0 +1,55 @@ +package shop.mtcoding.metamall.controller; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +class UserControllerTest { + + @Autowired + private MockMvc mockMvc; + + @BeforeEach + void setUp() { + } + + @Test + void login() throws Exception{ + //given + String requestBody = "{\"username\":\"ssar\", \"password\":1234}"; + + //when + mockMvc.perform(post("/login") + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()); + } + + + + @Test + void join() throws Exception{ + //given + String requestBody = "{\"username\":\"jju\", \"password\":1234, \"email\":\"1234@1234\"}"; + + //when + mockMvc.perform(post("/join") + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()); + } +} \ No newline at end of file From a63942ab27a5da4191e3fac117ddf0bc8626a813 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 16:00:36 +0900 Subject: [PATCH 16/27] =?UTF-8?q?[8-2]=20=EC=A0=9C=ED=92=88=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ProductController.java | 12 +- .../controller/ProductControllerTest.java | 131 ++++++++++++++++++ 2 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java index da146ba..c7060be 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -26,7 +26,7 @@ public class ProductController { private final ProductRepository productRepository; private final HttpSession session; - @GetMapping("/find") + @PostMapping("/find") public ResponseEntity find(@RequestBody ProductRequest.ProductDto product, HttpServletRequest request) { //인증만 필요 String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); @@ -65,7 +65,7 @@ public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletR Long userId = decodedJWT.getClaim("id").asLong(); - // 사용자의 권한 확인 SELLER(판매자), ADMIN(관리자)여야 등록 가능 + // 사용자의 권한 확인 SELLER(판매자) 등록 가능 String role = decodedJWT.getClaim("role").asString(); if(role.equals(Role.SELLER.toString())){ @@ -97,7 +97,7 @@ public ResponseEntity update(@PathVariable String productname, @RequestBody P productPS.setPrice(updateProduct.getPrice()); productPS.setQty(updateProduct.getQty()); - ResponseDto responseDto = new ResponseDto<>().data(updateProduct); + ResponseDto responseDto = new ResponseDto<>().data(productPS); return ResponseEntity.ok().body(responseDto); }else{ @@ -106,8 +106,8 @@ public ResponseEntity update(@PathVariable String productname, @RequestBody P } @Transactional - @DeleteMapping("/delete/{name}") - public ResponseEntity delete(@PathVariable String name, HttpServletRequest request){ + @DeleteMapping("/delete/{productname}") + public ResponseEntity delete(@PathVariable String productname, HttpServletRequest request){ String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); @@ -117,7 +117,7 @@ public ResponseEntity delete(@PathVariable String name, HttpServletRequest re String role = decodedJWT.getClaim("role").asString(); if(role.equals(Role.SELLER.toString())){ - Product productPS = productRepository.findByName(name).orElseThrow(() -> { + Product productPS = productRepository.findByName(productname).orElseThrow(() -> { return new Exception400("제품의 이름을 찾을 수 없습니다. "); }); //제품이 있는지 확인 diff --git a/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java new file mode 100644 index 0000000..c1d1c86 --- /dev/null +++ b/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java @@ -0,0 +1,131 @@ +package shop.mtcoding.metamall.controller; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import shop.mtcoding.metamall.model.user.User; +import shop.mtcoding.metamall.model.user.UserRepository; + +import java.util.Date; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +class ProductControllerTest { + + private static final String SUBJECT = "jwtstudy"; + private static final int EXP = 1000 * 60 * 60; + public static final String TOKEN_PREFIX = "Bearer "; // 스페이스 필요함 + public static final String HEADER = "Authorization"; + private static final String SECRET = "메타코딩"; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private UserRepository userRepository; + + private String jwt = ""; + + @BeforeEach + void setUp(){ +// User user = userRepository.findById(2L).get(); //ssar 유저 꺼내서 로그인시키기 + User user = userRepository.findById(1L).get(); //seller 유저 꺼내서 로그인시키기 + + + jwt = TOKEN_PREFIX + JWT.create() + .withSubject(SUBJECT) + .withExpiresAt(new Date(System.currentTimeMillis() + EXP)) + .withClaim("id", user.getId()) + .withClaim("role", user.getRole().toString()) + .sign(Algorithm.HMAC512(SECRET)); + // + } + + + @Test + void find() throws Exception{ + //given + String requestBody = "{\"name\":\"book1\"}"; //productDto 만들어서 전달 + + //then + MvcResult result = mockMvc.perform(post("/find") + .header(HEADER, jwt) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + + @Test + void findAll() throws Exception{ + //then + MvcResult result = mockMvc.perform(get("/findAll") + .header(HEADER, jwt)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + + @Test + void upload() throws Exception{ + //given + String requestBody = "{\"name\":\"book3\",\"price\":\"100000\",\"qty\":\"10\"}"; + + //then + MvcResult result = mockMvc.perform(post("/upload") + .header(HEADER, jwt) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + + @Test + void update() throws Exception{ + //given + String requestBody = "{\"name\":\"book2\",\"price\":\"12345\",\"qty\":\"10\"}"; // 수정할 물건 내용 book2를 수정 + + //then + MvcResult result = mockMvc.perform(put("/update/{productname}", "book2") + .header(HEADER, jwt) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + +// @Test +// void delete() throws Exception{ +// +// //then +// mockMvc.perform(delete("/delete/{productname}", "book2")) 이부분 다시 +// .header(HEADER, jwt) +// .contentType(MediaType.APPLICATION_JSON) +// .andExpect(status().isNoContent()); +// +// } +} \ No newline at end of file From 8d5b4809ba27380a1000d10d27b16dcb5725d8ff Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 16:50:06 +0900 Subject: [PATCH 17/27] =?UTF-8?q?[8-3]=20=EC=A3=BC=EB=AC=B8=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OrderControllerTest.java | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java diff --git a/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java new file mode 100644 index 0000000..f93e16a --- /dev/null +++ b/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java @@ -0,0 +1,158 @@ +package shop.mtcoding.metamall.controller; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.transaction.annotation.Transactional; +import shop.mtcoding.metamall.core.exception.Exception400; +import shop.mtcoding.metamall.core.exception.Exception404; +import shop.mtcoding.metamall.model.orderproduct.OrderProduct; +import shop.mtcoding.metamall.model.orderproduct.OrderProductRepository; +import shop.mtcoding.metamall.model.ordersheet.OrderSheet; +import shop.mtcoding.metamall.model.ordersheet.OrderSheetRepository; +import shop.mtcoding.metamall.model.product.Product; +import shop.mtcoding.metamall.model.product.ProductRepository; +import shop.mtcoding.metamall.model.user.User; +import shop.mtcoding.metamall.model.user.UserRepository; + +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +class OrderControllerTest { + + private static final String SUBJECT = "jwtstudy"; + private static final int EXP = 1000 * 60 * 60; + public static final String TOKEN_PREFIX = "Bearer "; // 스페이스 필요함 + public static final String HEADER = "Authorization"; + private static final String SECRET = "메타코딩"; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ProductRepository productRepository; + + @Autowired + private OrderProductRepository orderProductRepository; + + @Autowired + private OrderSheetRepository orderSheetRepository; + + private String jwt = ""; + + + @BeforeEach + @Transactional + void setUp() { + User user = userRepository.findById(2L).get(); //ssar 유저 꺼내서 로그인시키기 +// User user = userRepository.findById(1L).get(); //seller 유저 꺼내서 로그인시키기 + + jwt = TOKEN_PREFIX + JWT.create() + .withSubject(SUBJECT) + .withExpiresAt(new Date(System.currentTimeMillis() + EXP)) + .withClaim("id", user.getId()) + .withClaim("role", user.getRole().toString()) + .sign(Algorithm.HMAC512(SECRET)); + + // ssar의 book1 주문 만들기, seller는 안됨 ordersheet 없음 + Product productPS = productRepository.findByName("book1").get(); + + productPS.setQty(productPS.getQty() - 10); //10개 주문, 수량 업데이트 + OrderProduct orderProduct = OrderProduct.builder().product(productPS).count(10).orderPrice(productPS.getPrice() * 10).build(); + orderProductRepository.save(orderProduct); + + OrderSheet orderSheetPS = orderSheetRepository.findByUserId(user.getId()).get(); + + List orderProductList = orderSheetPS.getOrderProductList(); + orderProductList.add(orderProduct); + orderSheetPS.setOrderProductList(orderProductList); //orderProduct 추가된 리스트로 업데이트 +// + Integer totalPrice = orderSheetPS.getTotalPrice(); + totalPrice = totalPrice + orderProduct.getOrderPrice(); + orderSheetPS.setTotalPrice(totalPrice); + + orderProduct.setOrderSheet(orderSheetPS.getId()); + + User seller = userRepository.findById(1L).get(); //seller 유저 꺼내서 로그인시키기 + + jwt = TOKEN_PREFIX + JWT.create() + .withSubject(SUBJECT) + .withExpiresAt(new Date(System.currentTimeMillis() + EXP)) + .withClaim("id", seller.getId()) + .withClaim("role", seller.getRole().toString()) + .sign(Algorithm.HMAC512(SECRET)); + } + + @Test + void order() throws Exception{ + //given + String requestBody = "{\"name\":\"book1\",\"count\":\"10\"}"; //OrderDto 만들어서 전달 + + //then + MvcResult result = mockMvc.perform(post("/order") + .header(HEADER, jwt) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + + @Test + @Transactional + void findAllOrder() throws Exception{ + //then + MvcResult result = mockMvc.perform(get("/findAllOrder") + .header(HEADER, jwt)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + + @Test + @Transactional + void cancel() throws Exception{ + MvcResult result = mockMvc.perform(delete("/cancel") + .header(HEADER, jwt)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } + + @Test + @Transactional + void cancelSeller() throws Exception{ + MvcResult result = mockMvc.perform(delete("/cancel/{userId}", 2L) //ssar의 주문 취소 + .header(HEADER, jwt)) //Role이 Seller여야 함 + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); + } +} \ No newline at end of file From ab589d4b49a6e355deab9b7ce6e1de3090673824 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 21:36:40 +0900 Subject: [PATCH 18/27] =?UTF-8?q?[8-2+]=20=EC=A0=9C=ED=92=88=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20del?= =?UTF-8?q?ete=EC=B6=94=EA=B0=80=20(=EC=9D=B4=EC=9C=A0=20:=20mockMvc?= =?UTF-8?q?=EC=9D=98=20delete=EC=99=80=20=EC=9D=B4=EB=A6=84=EC=9D=B4=20?= =?UTF-8?q?=EA=B0=99=EC=95=84=EC=84=9C=20=EC=83=9D=EA=B8=B4=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EB=B0=9C=EC=83=9D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ProductControllerTest.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java index c1d1c86..429cb4e 100644 --- a/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java +++ b/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java @@ -12,6 +12,7 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import org.springframework.transaction.annotation.Transactional; import shop.mtcoding.metamall.model.user.User; import shop.mtcoding.metamall.model.user.UserRepository; @@ -118,14 +119,14 @@ void update() throws Exception{ System.out.println(content); } -// @Test -// void delete() throws Exception{ -// -// //then -// mockMvc.perform(delete("/delete/{productname}", "book2")) 이부분 다시 -// .header(HEADER, jwt) -// .contentType(MediaType.APPLICATION_JSON) -// .andExpect(status().isNoContent()); -// -// } + @Test + @Transactional + void delete_Test() throws Exception{ + //then + mockMvc.perform(delete("/delete/{productname}", "book2") + .header(HEADER, jwt) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + } } \ No newline at end of file From 0ea85b4d64f810a9c4017e4f92641fbe877e9982 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 21:42:55 +0900 Subject: [PATCH 19/27] =?UTF-8?q?[9-1]=20=EA=B3=A0=EA=B0=9D=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/mtcoding/metamall/controller/UserController.java | 5 +++-- .../java/shop/mtcoding/metamall/dto/user/UserRequest.java | 4 ++++ src/main/java/shop/mtcoding/metamall/model/user/User.java | 8 ++++++-- .../mtcoding/metamall/controller/UserControllerTest.java | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/controller/UserController.java b/src/main/java/shop/mtcoding/metamall/controller/UserController.java index f3e7535..49c85fd 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/UserController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/UserController.java @@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import javax.validation.Valid; import java.time.LocalDateTime; import java.util.Optional; @@ -34,7 +35,7 @@ public class UserController { private final HttpSession session; @PostMapping("/login") - public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpServletRequest request) { + public ResponseEntity login(@Valid @RequestBody UserRequest.LoginDto loginDto, HttpServletRequest request) { session.setAttribute("login", null); Optional userOP = userRepository.findByUsername(loginDto.getUsername()); if (userOP.isPresent()) { @@ -74,7 +75,7 @@ public ResponseEntity login(@RequestBody UserRequest.LoginDto loginDto, HttpS } @PostMapping("/join") - public ResponseEntity join(@RequestBody User joinUser){ + public ResponseEntity join(@Valid @RequestBody User joinUser){ joinUser.setRole(Role.USER); userRepository.save(joinUser); OrderSheet orderSheet = OrderSheet.builder().user(joinUser).totalPrice(0).build(); diff --git a/src/main/java/shop/mtcoding/metamall/dto/user/UserRequest.java b/src/main/java/shop/mtcoding/metamall/dto/user/UserRequest.java index 80947db..39554f9 100644 --- a/src/main/java/shop/mtcoding/metamall/dto/user/UserRequest.java +++ b/src/main/java/shop/mtcoding/metamall/dto/user/UserRequest.java @@ -3,10 +3,14 @@ import lombok.Getter; import lombok.Setter; +import javax.validation.constraints.NotBlank; + public class UserRequest { @Getter @Setter public static class LoginDto { + @NotBlank(message = "고객명 입력은 필수입니다") private String username; + @NotBlank(message = "비밀번호 입력은 필수입니다") private String password; } } diff --git a/src/main/java/shop/mtcoding/metamall/model/user/User.java b/src/main/java/shop/mtcoding/metamall/model/user/User.java index bd4a86b..e56f1d5 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/User.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/User.java @@ -7,6 +7,7 @@ import org.hibernate.annotations.CreationTimestamp; import javax.persistence.*; +import javax.validation.constraints.NotBlank; import java.sql.Timestamp; import java.time.LocalDateTime; @@ -19,10 +20,13 @@ public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = false, length = 30) + @NotBlank(message = " 입력은 필수입니다") + @Column(length = 30) private String username; - @Column(nullable = false, length = 100) + @NotBlank(message = " 입력은 필수입니다") + @Column(length = 100) private String password; + @NotBlank(message = " 입력은 필수입니다") @Column(nullable = false, length = 50) private String email; private Role role; // USER(고객), SELLER(판매자), ADMIN(관리자) diff --git a/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java index 5bd24c4..13eeffe 100644 --- a/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java +++ b/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java @@ -32,7 +32,7 @@ void login() throws Exception{ //given String requestBody = "{\"username\":\"ssar\", \"password\":1234}"; - //when + //then mockMvc.perform(post("/login") .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) @@ -46,7 +46,7 @@ void join() throws Exception{ //given String requestBody = "{\"username\":\"jju\", \"password\":1234, \"email\":\"1234@1234\"}"; - //when + //then mockMvc.perform(post("/join") .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) From c4b4de80e4c6ac685ba13c890b9198d43fac7f57 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 21:45:01 +0900 Subject: [PATCH 20/27] =?UTF-8?q?[9-2]=20=EC=A0=9C=ED=92=88=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ProductController.java | 21 +++++++++---------- .../metamall/dto/product/ProductRequest.java | 6 +++++- .../metamall/model/product/Product.java | 16 ++++++++++---- .../model/product/ProductRepository.java | 4 ++-- .../model/product/ProductRepositoryTest.java | 2 +- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java index c7060be..163bc34 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -3,7 +3,6 @@ import com.auth0.jwt.interfaces.DecodedJWT; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import shop.mtcoding.metamall.core.exception.Exception400; import shop.mtcoding.metamall.core.exception.Exception403; @@ -16,6 +15,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import javax.validation.Valid; import java.util.List; import java.util.Optional; @@ -27,14 +27,13 @@ public class ProductController { private final HttpSession session; @PostMapping("/find") - public ResponseEntity find(@RequestBody ProductRequest.ProductDto product, HttpServletRequest request) { + public ResponseEntity find(@Valid @RequestBody ProductRequest.ProductDto product, HttpServletRequest request) { //인증만 필요 String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); - Long userId = decodedJWT.getClaim("id").asLong(); - Optional productOP = productRepository.findByName(product.getName()); + Optional productOP = productRepository.findByName(product.getProductname()); if (productOP.isPresent()) { // 1. 물건 정보 꺼내기 Product findProduct = productOP.get(); @@ -49,6 +48,7 @@ public ResponseEntity find(@RequestBody ProductRequest.ProductDto product, Ht @GetMapping("/findAll") public ResponseEntity findAll(HttpServletRequest request) { + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); @@ -58,7 +58,7 @@ public ResponseEntity findAll(HttpServletRequest request) { } @PostMapping("/upload") - public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletRequest request){ + public ResponseEntity upload(@Valid @RequestBody Product uploadProduct, HttpServletRequest request){ String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); @@ -77,9 +77,8 @@ public ResponseEntity upload(@RequestBody Product uploadProduct, HttpServletR } } - @Transactional - @PutMapping("/update/{productname}") - public ResponseEntity update(@PathVariable String productname, @RequestBody Product updateProduct, HttpServletRequest request){ + @PutMapping("/update/{productname}") // 값 안들어오면 404 반환 + public ResponseEntity update(@PathVariable(required = false) String productname, @Valid @RequestBody Product updateProduct, HttpServletRequest request){ String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); @@ -105,9 +104,9 @@ public ResponseEntity update(@PathVariable String productname, @RequestBody P } } - @Transactional - @DeleteMapping("/delete/{productname}") - public ResponseEntity delete(@PathVariable String productname, HttpServletRequest request){ + + @DeleteMapping("/delete/{productname}") // 값 안들어오면 404 반환 + public ResponseEntity delete(@PathVariable(required = false) String productname, HttpServletRequest request){ String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); diff --git a/src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java b/src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java index f25b376..826ab61 100644 --- a/src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java +++ b/src/main/java/shop/mtcoding/metamall/dto/product/ProductRequest.java @@ -3,9 +3,13 @@ import lombok.Getter; import lombok.Setter; +import javax.validation.constraints.NotBlank; + public class ProductRequest { @Getter @Setter public static class ProductDto { - private String name; + + @NotBlank(message = " 입력은 필수입니다") + private String productname; } } diff --git a/src/main/java/shop/mtcoding/metamall/model/product/Product.java b/src/main/java/shop/mtcoding/metamall/model/product/Product.java index b58762b..95e34cc 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/Product.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/Product.java @@ -6,6 +6,8 @@ import lombok.Setter; import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import java.time.LocalDateTime; @NoArgsConstructor @@ -17,12 +19,18 @@ public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @NotBlank(message = "입력은 필수입니다") @Column(nullable = false, length = 50) - private String name; // 상품 이름 + private String productname; // 상품 이름 + + @NotNull(message = "입력은 필수입니다") @Column(nullable = false, length = Integer.MAX_VALUE) private Integer price; // 상품 가격 + + @NotNull(message = "입력은 필수입니다") @Column(nullable = false, length = Integer.MAX_VALUE) private Integer qty; // 상품 재고 + private LocalDateTime createdAt; private LocalDateTime updatedAt; @@ -37,9 +45,9 @@ protected void onUpdate() { } @Builder - public Product(Long id, String name, Integer price, Integer qty, LocalDateTime createdAt, LocalDateTime updatedAt) { + public Product(Long id, String productname, Integer price, Integer qty, LocalDateTime createdAt, LocalDateTime updatedAt) { this.id = id; - this.name = name; + this.productname = productname; this.price = price; this.qty = qty; this.createdAt = createdAt; @@ -50,7 +58,7 @@ public Product(Long id, String name, Integer price, Integer qty, LocalDateTime c public String toString() { return "Product{" + "id=" + id + - ", name='" + name + '\'' + + ", productname='" + productname + '\'' + ", price=" + price + ", qty=" + qty + '}'; diff --git a/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java b/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java index cfa4f1d..9b659c3 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/ProductRepository.java @@ -7,6 +7,6 @@ import java.util.Optional; public interface ProductRepository extends JpaRepository { - @Query("select p from Product p where p.name = :name") - Optional findByName(@Param("name") String name); + @Query("select p from Product p where p.productname = :productname") + Optional findByName(@Param("productname") String productname); } diff --git a/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java b/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java index 7557627..04a2bfd 100644 --- a/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java +++ b/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java @@ -22,7 +22,7 @@ class ProductRepositoryTest { void findByName() { //given String productname = "phone"; - Product product = Product.builder().name(productname).price(1000).qty(10).build(); // id : 3 + Product product = Product.builder().productname(productname).price(1000).qty(10).build(); // id : 3 productRepository.save(product); //when Product findProduct = productRepository.findByName(productname).get(); From a974b6e89e4ec26cd20861668f7afb35202cf204 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 21:55:53 +0900 Subject: [PATCH 21/27] =?UTF-8?q?[9-3]=20=EC=A3=BC=EB=AC=B8=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/mtcoding/metamall/controller/OrderController.java | 7 ++++--- .../shop/mtcoding/metamall/dto/order/OrderRequest.java | 5 +++++ .../mtcoding/metamall/controller/OrderControllerTest.java | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java index ed359a9..bf60e96 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/OrderController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/OrderController.java @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import javax.validation.Valid; import java.util.List; import java.util.Optional; @@ -39,7 +40,7 @@ public class OrderController { @PostMapping("/order") @Transactional - public ResponseEntity order(@RequestBody OrderRequest.OrderDto orderDto, HttpServletRequest request) { + public ResponseEntity order(@Valid @RequestBody OrderRequest.OrderDto orderDto, HttpServletRequest request) { String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); @@ -130,8 +131,8 @@ public ResponseEntity cancel(HttpServletRequest request){ } } - @DeleteMapping("/cancel/{userId}") - public ResponseEntity cancelSeller(@PathVariable Long userId, HttpServletRequest request){ + @DeleteMapping("/cancel/{userId}") // 값 안들어오면 seller의 user cancel로 판단해서 403 - 잘못된 접근 + public ResponseEntity cancelSeller(@PathVariable(required = false) Long userId, HttpServletRequest request){ String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); diff --git a/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java b/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java index 5671429..769cb78 100644 --- a/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java +++ b/src/main/java/shop/mtcoding/metamall/dto/order/OrderRequest.java @@ -5,10 +5,15 @@ import shop.mtcoding.metamall.model.product.Product; import shop.mtcoding.metamall.model.user.User; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + public class OrderRequest { @Getter @Setter public static class OrderDto { + @NotBlank(message = "입력은 필수입니다") private String name; + @NotNull(message = "입력은 필수입니다") private Integer count; } } diff --git a/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java index f93e16a..3f4756a 100644 --- a/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java +++ b/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java @@ -103,6 +103,7 @@ void setUp() { } @Test + @Transactional void order() throws Exception{ //given String requestBody = "{\"name\":\"book1\",\"count\":\"10\"}"; //OrderDto 만들어서 전달 From 4746b506bf922be1efa0bcc86dbcd6179521af91 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 21:58:47 +0900 Subject: [PATCH 22/27] =?UTF-8?q?temp=20:=20Annotation=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EA=B9=8C=EC=A7=80=20=EC=99=84=EB=A3=8C,=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++- .../metamall/MetamallApplication.java | 4 +-- .../metamall/core/advice/AuthorizeAdvice.java | 34 +++++++++++++++++++ .../metamall/core/advice/ErrorLogAdvice.java | 31 +++++++++++++++++ .../core/advice/MyExceptionAdvice.java | 14 ++++++++ .../metamall/core/anotation/Authorize.java | 4 +++ .../metamall/core/anotation/ErrorLog.java | 4 +++ 7 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 src/main/java/shop/mtcoding/metamall/core/advice/AuthorizeAdvice.java create mode 100644 src/main/java/shop/mtcoding/metamall/core/advice/ErrorLogAdvice.java create mode 100644 src/main/java/shop/mtcoding/metamall/core/anotation/Authorize.java create mode 100644 src/main/java/shop/mtcoding/metamall/core/anotation/ErrorLog.java diff --git a/build.gradle b/build.gradle index 4943187..31d3826 100644 --- a/build.gradle +++ b/build.gradle @@ -22,12 +22,14 @@ dependencies { implementation group: 'com.auth0', name: 'java-jwt', version: '4.3.0' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'junit:junit:4.13.1' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' -} + } tasks.named('test') { useJUnitPlatform() diff --git a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java index e8e2e26..03bd70b 100644 --- a/src/main/java/shop/mtcoding/metamall/MetamallApplication.java +++ b/src/main/java/shop/mtcoding/metamall/MetamallApplication.java @@ -34,10 +34,10 @@ CommandLineRunner initData(UserRepository userRepository, ProductRepository prod OrderSheet orderSheet = OrderSheet.builder().user(ssar).totalPrice(0).build(); orderSheetRepository.save(orderSheet); // 한 고객 당 주문 시트 생성 - Product book = Product.builder().name("book1").price(10000).qty(100).build(); + Product book = Product.builder().productname("book1").price(10000).qty(100).build(); productRepository.save(book); - Product book2 = Product.builder().name("book2").price(15000).qty(100).build(); + Product book2 = Product.builder().productname("book2").price(15000).qty(100).build(); productRepository.save(book2); }; } diff --git a/src/main/java/shop/mtcoding/metamall/core/advice/AuthorizeAdvice.java b/src/main/java/shop/mtcoding/metamall/core/advice/AuthorizeAdvice.java new file mode 100644 index 0000000..f4614be --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/core/advice/AuthorizeAdvice.java @@ -0,0 +1,34 @@ +package shop.mtcoding.metamall.core.advice; + + +import com.auth0.jwt.interfaces.DecodedJWT; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import shop.mtcoding.metamall.core.jwt.JwtProvider; + +import javax.servlet.http.HttpServletRequest; + +@Aspect +@Component +public class AuthorizeAdvice { + + //깃발에 별칭주기 + @Pointcut("@annotation(shop.mtcoding.metamall.core.anotation.Authorize)") + public void authorize(){} + + + @Around("authorize()") + public Object authAdvice(ProceedingJoinPoint jp) throws Throwable{ + + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); + String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); + DecodedJWT decodedJWT = JwtProvider.verify(jwt); + + return jp.proceed(); + } +} diff --git a/src/main/java/shop/mtcoding/metamall/core/advice/ErrorLogAdvice.java b/src/main/java/shop/mtcoding/metamall/core/advice/ErrorLogAdvice.java new file mode 100644 index 0000000..6e2b276 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/core/advice/ErrorLogAdvice.java @@ -0,0 +1,31 @@ +package shop.mtcoding.metamall.core.advice; + + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import shop.mtcoding.metamall.dto.user.UserRequest; + +@Aspect +@Component +public class ErrorLogAdvice { + + //깃발에 별칭주기 + @Pointcut("@annotation(shop.mtcoding.metamall.core.anotation.ErrorLog)") + public void errorLog(){} + + + @Before("errorLog()") + public void errorAdvice(JoinPoint jp) throws Throwable{ + Object[] args = jp.getArgs(); + + for (Object arg : args) { + if(arg instanceof UserRequest.LoginDto){ + + System.out.println(((UserRequest.LoginDto) arg).getUsername()+"님 안녕"); + } + } + } +} diff --git a/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java b/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java index 831c363..d138e73 100644 --- a/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java +++ b/src/main/java/shop/mtcoding/metamall/core/advice/MyExceptionAdvice.java @@ -2,8 +2,11 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import shop.mtcoding.metamall.core.exception.*; @@ -12,6 +15,8 @@ import shop.mtcoding.metamall.model.log.err.ErrorLogRepository; import javax.servlet.http.HttpSession; +import java.util.List; +import java.util.stream.Collectors; @Slf4j @RequiredArgsConstructor @@ -72,4 +77,13 @@ public ResponseEntity serverError(Exception500 e) { } return new ResponseEntity<>(e.body(), e.status()); } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity validError(MethodArgumentNotValidException e) { + BindingResult result = e.getBindingResult(); + List errorMessages = result.getFieldErrors().stream() + .map(error -> error.getField() + " " + error.getDefaultMessage()) + .collect(Collectors.toList()); + return ResponseEntity.badRequest().body(errorMessages); + } } \ No newline at end of file diff --git a/src/main/java/shop/mtcoding/metamall/core/anotation/Authorize.java b/src/main/java/shop/mtcoding/metamall/core/anotation/Authorize.java new file mode 100644 index 0000000..e756312 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/core/anotation/Authorize.java @@ -0,0 +1,4 @@ +package shop.mtcoding.metamall.core.anotation; + +public @interface Authorize { +} diff --git a/src/main/java/shop/mtcoding/metamall/core/anotation/ErrorLog.java b/src/main/java/shop/mtcoding/metamall/core/anotation/ErrorLog.java new file mode 100644 index 0000000..0db7191 --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/core/anotation/ErrorLog.java @@ -0,0 +1,4 @@ +package shop.mtcoding.metamall.core.anotation; + +public @interface ErrorLog { +} From b8b79b859b9a912113a8788cd1cafe2c9f9e7ecc Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 22:27:49 +0900 Subject: [PATCH 23/27] =?UTF-8?q?[10]=20User=EC=9D=98=20=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20JsonIgnore=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20(=EB=AF=BC=EA=B0=90=ED=95=9C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/orderproduct/OrderProduct.java | 2 +- .../metamall/model/product/Product.java | 2 +- .../mtcoding/metamall/model/user/User.java | 7 +++++-- .../controller/UserControllerTest.java | 18 +++++++++++++----- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java b/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java index c5226ec..0d94069 100644 --- a/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java +++ b/src/main/java/shop/mtcoding/metamall/model/orderproduct/OrderProduct.java @@ -11,8 +11,8 @@ import java.time.LocalDateTime; @NoArgsConstructor -@Setter // DTO 만들면 삭제해야됨 @Getter +@Setter @Table(name = "order_product_tb") @Entity public class OrderProduct { // 주문 상품 diff --git a/src/main/java/shop/mtcoding/metamall/model/product/Product.java b/src/main/java/shop/mtcoding/metamall/model/product/Product.java index 95e34cc..0c0ca72 100644 --- a/src/main/java/shop/mtcoding/metamall/model/product/Product.java +++ b/src/main/java/shop/mtcoding/metamall/model/product/Product.java @@ -11,8 +11,8 @@ import java.time.LocalDateTime; @NoArgsConstructor -@Setter // DTO 만들면 삭제해야됨 @Getter +@Setter @Table(name = "product_tb") @Entity public class Product { diff --git a/src/main/java/shop/mtcoding/metamall/model/user/User.java b/src/main/java/shop/mtcoding/metamall/model/user/User.java index e56f1d5..554a67a 100644 --- a/src/main/java/shop/mtcoding/metamall/model/user/User.java +++ b/src/main/java/shop/mtcoding/metamall/model/user/User.java @@ -1,5 +1,7 @@ package shop.mtcoding.metamall.model.user; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -12,8 +14,8 @@ import java.time.LocalDateTime; @NoArgsConstructor -@Setter // DTO 만들면 삭제해야됨 @Getter +@Setter @Table(name = "user_tb") @Entity public class User { @@ -23,11 +25,12 @@ public class User { @NotBlank(message = " 입력은 필수입니다") @Column(length = 30) private String username; + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @NotBlank(message = " 입력은 필수입니다") @Column(length = 100) private String password; @NotBlank(message = " 입력은 필수입니다") - @Column(nullable = false, length = 50) + @Column(length = 50) private String email; private Role role; // USER(고객), SELLER(판매자), ADMIN(관리자) private LocalDateTime createdAt; diff --git a/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java index 13eeffe..a1b9b64 100644 --- a/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java +++ b/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java @@ -9,6 +9,7 @@ import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; import static org.junit.jupiter.api.Assertions.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -33,10 +34,13 @@ void login() throws Exception{ String requestBody = "{\"username\":\"ssar\", \"password\":1234}"; //then - mockMvc.perform(post("/login") + MvcResult result = mockMvc.perform(post("/login") .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andReturn(); + String content = result.getResponse().getContentAsString(); + System.out.println(content); } @@ -44,12 +48,16 @@ void login() throws Exception{ @Test void join() throws Exception{ //given - String requestBody = "{\"username\":\"jju\", \"password\":1234, \"email\":\"1234@1234\"}"; + String requestBody = "{\"username\":\"jju\", \"password\":\"1234\", \"email\":\"1234@1234\"}"; //then - mockMvc.perform(post("/join") + MvcResult result = mockMvc.perform(post("/join") .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println(content); } } \ No newline at end of file From 5b4db1399a70e42b000dae962fb0a8a7bd071809 Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 22:51:39 +0900 Subject: [PATCH 24/27] =?UTF-8?q?[3+]=20=EB=AC=BC=EA=B1=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mtcoding/metamall/controller/ProductController.java | 6 +++--- .../mtcoding/metamall/controller/ProductControllerTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java index 163bc34..2ad6e8a 100644 --- a/src/main/java/shop/mtcoding/metamall/controller/ProductController.java +++ b/src/main/java/shop/mtcoding/metamall/controller/ProductController.java @@ -77,8 +77,8 @@ public ResponseEntity upload(@Valid @RequestBody Product uploadProduct, HttpS } } - @PutMapping("/update/{productname}") // 값 안들어오면 404 반환 - public ResponseEntity update(@PathVariable(required = false) String productname, @Valid @RequestBody Product updateProduct, HttpServletRequest request){ + @PutMapping("/update") + public ResponseEntity update(@Valid @RequestBody Product updateProduct, HttpServletRequest request){ String jwt = request.getHeader(JwtProvider.HEADER).replaceAll("Bearer ", ""); DecodedJWT decodedJWT = JwtProvider.verify(jwt); @@ -89,7 +89,7 @@ public ResponseEntity update(@PathVariable(required = false) String productna if(role.equals(Role.SELLER.toString())){ - Product productPS = productRepository.findByName(productname).orElseThrow(() -> { + Product productPS = productRepository.findByName(updateProduct.getProductname()).orElseThrow(() -> { return new Exception400("제품의 이름을 찾을 수 없습니다. "); }); //영속화 하기 diff --git a/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java b/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java index 429cb4e..5affa68 100644 --- a/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java +++ b/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java @@ -105,10 +105,10 @@ void upload() throws Exception{ @Test void update() throws Exception{ //given - String requestBody = "{\"name\":\"book2\",\"price\":\"12345\",\"qty\":\"10\"}"; // 수정할 물건 내용 book2를 수정 + String requestBody = "{\"productname\":\"book2\",\"price\":\"12345\",\"qty\":\"10\"}"; // 수정할 물건 내용 book2를 수정 //then - MvcResult result = mockMvc.perform(put("/update/{productname}", "book2") + MvcResult result = mockMvc.perform(put("/update") .header(HEADER, jwt) .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) From fae109f581364c1aa7feaf463fab8bbd82e6b28a Mon Sep 17 00:00:00 2001 From: HJoo Date: Sun, 9 Apr 2023 23:01:47 +0900 Subject: [PATCH 25/27] =?UTF-8?q?[**=20API=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80**]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/shop/mtcoding/metamall/api | 327 +++++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 src/main/java/shop/mtcoding/metamall/api diff --git a/src/main/java/shop/mtcoding/metamall/api b/src/main/java/shop/mtcoding/metamall/api new file mode 100644 index 0000000..9a3521f --- /dev/null +++ b/src/main/java/shop/mtcoding/metamall/api @@ -0,0 +1,327 @@ +1. 회원가입 (POST) + 요청 주소 + - http://localhost:8080/join + 요청 파라미터 + - application/json + { + "username" : "jju", + "password" : "1234", + "email" : "yoo@a,a" + } + 응답 바디 + - application/json + { + "status": 200, + "msg": "성공", + "data": { + "id": 4, + "username": "jju", + "email": "yoo@a,a", + "role": "USER", + "createdAt": "2023-04-09T22:37:00.4652234", + "updatedAt": null + } + } + +2. 로그인 (POST) + 요청 주소 + - http://localhost:8080/login + 요청 파라미터 + - application/json + { + "username" : "jju", + "password" : "1234" + } + + 응답 바디 + - application/json + { + "status": 200, + "msg": "성공", + "data": { + "id": 3, + "username": "jju", + "email": "yoo@a,a", + "role": "USER", + "createdAt": "2023-04-09T22:38:19.389678", + "updatedAt": "2023-04-09T22:38:22.6968692" + } + } + +3. 상품등록 (POST) + 요청 주소 + - http://localhost:8080/upload + 요청 헤더 + - Authorization : Bearer ~ 요청 파라미터 + - + { + "productname" : "phone", + "price" : "500000", + "qty" : "100" + } + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": { + "id": 3, + "productname": "phone", + "price": 500000, + "qty": 100, + "createdAt": "2023-04-09T22:40:20.4367407", + "updatedAt": null + } + } + +4. 상품목록보기 (GET) + 요청 주소 + - http://localhost:8080/findAll + 요청 헤더 + - Authorization : Bearer ~ + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": [ + { + "id": 1, + "productname": "book1", + "price": 10000, + "qty": 100, + "createdAt": "2023-04-09T22:38:10.774707", + "updatedAt": null + }, + { + "id": 2, + "productname": "book2", + "price": 15000, + "qty": 100, + "createdAt": "2023-04-09T22:38:10.777716", + "updatedAt": null + }, + { + "id": 3, + "productname": "phone", + "price": 500000, + "qty": 100, + "createdAt": "2023-04-09T22:40:20.436741", + "updatedAt": null + } + ] + } + +5. 상품상세보기 (POST) + 요청 주소 + - http://localhost:8080/find + 요청 헤더 + - Authorization : Bearer ~ + 요청 파라미터 + - + { + "productname" : "phone" + } + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": { + "id": 3, + "productname": "phone", + "price": 500000, + "qty": 100, + "createdAt": "2023-04-09T22:40:20.436741", + "updatedAt": null + } + } + +6. 상품수정하기 (PUT) + 요청 주소 + - http://localhost:8080/update + 요청 헤더 + - Authorization : Bearer ~ + 요청 파라미터 + - + { + "productname":"phone", + "price" : "11111", + "qty" : "1010" + } + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": { + "id": 3, + "productname": "phone", + "price": 11111, + "qty": 1010, + "createdAt": "2023-04-09T22:52:36.532541", + "updatedAt": null + } + } + +7. 상품삭제하기 (DELETE) + 요청 주소 + - http://localhost:8080/delete/phone + 요청 헤더 + - + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": "Delete Success!" + } + +8. 주문하기 (POST) - OrderProduct를 생성하여, OrderSheet에 추가하세요 + 요청 주소 + - http://localhost:8080/order + 요청 헤더 + - Authorization : Bearer ~ + 요청 파라미터 + - + { + "name" : "book1", + "count" : "3" + } + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": { + "id": 1, + "user": { + "id": 2, + "username": "ssar", + "email": "ssar@nate.com", + "role": "USER", + "createdAt": "2023-04-09T22:50:25.430306", + "updatedAt": "2023-04-09T22:54:36.025102" + }, + "orderProductList": [ + { + "id": 1, + "product": { + "id": 1, + "productname": "book1", + "price": 10000, + "qty": 97, + "createdAt": "2023-04-09T22:50:25.450303", + "updatedAt": "2023-04-09T22:54:47.5028385" + }, + "count": 3, + "orderPrice": 30000, + "createdAt": "2023-04-09T22:54:47.4436669", + "orderSheet": 1 + } + ], + "totalPrice": 30000, + "createdAt": "2023-04-09T22:50:25.434301", + "updatedAt": "2023-04-09T22:54:47.5028385" + } + } + +9. 고객입장 - 주문목록보기 (GET) + 요청 주소 + - http://localhost:8080/findAllOrder + 요청 헤더 + - Authorization : Bearer ~ + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": [ + { + "id": 1, + "product": { + "id": 1, + "productname": "book1", + "price": 10000, + "qty": 97, + "createdAt": "2023-04-09T22:50:25.450303", + "updatedAt": "2023-04-09T22:54:47.502839" + }, + "count": 3, + "orderPrice": 30000, + "createdAt": "2023-04-09T22:54:47.443667", + "orderSheet": 1 + } + ] + } + +10. 판매자입장 - 주문목록보기 (GET) + 요청 주소 + - http://localhost:8080/findAllOrder + 요청 헤더 + - Authorization : Bearer ~ + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": [ + { + "id": 1, + "user": { + "id": 2, + "username": "ssar", + "email": "ssar@nate.com", + "role": "USER", + "createdAt": "2023-04-09T22:50:25.430306", + "updatedAt": "2023-04-09T22:54:36.025102" + }, + "orderProductList": [ + { + "id": 1, + "product": { + "id": 1, + "productname": "book1", + "price": 10000, + "qty": 97, + "createdAt": "2023-04-09T22:50:25.450303", + "updatedAt": "2023-04-09T22:54:47.502839" + }, + "count": 3, + "orderPrice": 30000, + "createdAt": "2023-04-09T22:54:47.443667", + "orderSheet": 1 + } + ], + "totalPrice": 30000, + "createdAt": "2023-04-09T22:50:25.434301", + "updatedAt": "2023-04-09T22:54:47.502839" + } + ] + } + +11. 고객입장 - 주문취소하기 (DELETE) - Casecade 옵션을 활용하세요. (양방향 매핑) + 요청 주소 + - http://localhost:8080/cancel + 요청 헤더 + - Authorization : Bearer ~ + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": "주문이 정상적으로 취소되었습니다. " + } + +12. 판매자입장 - 주문취소하기 (DELETE) - Casecade 옵션을 활용하세요. (양방향 매핑) + 요청 주소 + - http://localhost:8080/cancel/2 + 요청 헤더 + - Authorization : Bearer ~ + 응답 바디 + - + { + "status": 200, + "msg": "성공", + "data": "2번 고객의 주문이 정상적으로 취소되었습니다. " + } From 059dc732b4e58a2ff97840bfed32b52534d2112b Mon Sep 17 00:00:00 2001 From: hjoo <92681117+yhj1129@users.noreply.github.com> Date: Sun, 9 Apr 2023 23:35:39 +0900 Subject: [PATCH 26/27] Update README.md --- README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/README.md b/README.md index 8b13789..48b52b7 100644 --- a/README.md +++ b/README.md @@ -1 +1,81 @@ +![thumbnail (3)](https://user-images.githubusercontent.com/92681117/230777373-47f9c91c-7bea-4a1b-adc7-27bed9b14843.png) +# 🛒쇼핑몰 프로젝트 +## 👩🏻‍💻참여 +- 유현주 + +## ⚒️기술스택 +- **SpringBoot** + +## 🔧협업 도구 +- **Git** +- **GitHub** + +## 🗂️데이터베이스 +- **H2** + +## ➕의존성 +```java +dependencies { + implementation group: 'com.auth0', name: 'java-jwt', version: '4.3.0' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'junit:junit:4.13.1' + compileOnly 'org.projectlombok:lombok' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + runtimeOnly 'com.h2database:h2' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + } +``` + +## 💡구현된 기능 + +### 🙋🏻‍♀️사용자 기능 + - 회원가입 + - 로그인 + +### 👜상품 관련 기능 + - 판매자의 상품 등록 + - 등록된 상품들 목록 보기 + - 상품 상세보기 + - 판매자의 상품 수정 + - 판매자의 상품 삭제 + +### 👩🏻‍💻주문 관련 기능 + - 상품 주문 + - 고객 주문 목록 보기 + - 판매자의 전체 고객 주문 목록 보기 + +**상세한 요청과 응답은 [api문서](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/main/java/shop/mtcoding/metamall/api)를 확인** + +## 👩🏻‍🔧작성한 테스트 코드 +- 레포지토리 쿼리 테스트 코드 + + [고객 쿼리](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/test/java/shop/mtcoding/metamall/model/user/UserRepositoryTest.java) + + [제품 쿼리](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/test/java/shop/mtcoding/metamall/model/product/ProductRepositoryTest.java) + + [주문서 쿼리](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/test/java/shop/mtcoding/metamall/model/ordersheet/OrderSheetRepositoryTest.java) + +- 컨트롤러 테스트 코드 + + [고객 컨트롤러](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/test/java/shop/mtcoding/metamall/controller/UserControllerTest.java) + + [상품 컨트롤러](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/test/java/shop/mtcoding/metamall/controller/ProductControllerTest.java) + + [주문 컨트롤러](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/test/java/shop/mtcoding/metamall/controller/OrderControllerTest.java) + +## 🔧보완할 점 +- 요청에 대해 Dto로 받지 못한 것들이 몇 가지 있었다. 새로 Dto를 추가해서 요청에 맞는 Dto로 요청을 처리하도록 변경할 예정이다. +- 유효성 검사 추가. 현재 null, "" 체크 정도만 구현되어 있다. +- 데이터베이스 연관관계를 좀 더 공부해서 응답이 더 깔끔하게 나올 수 있도록 변경할 예정. 불필요하게 많은 정보의 응답이 나온다고 느꼈다. +- ER-Diagram을 보완하기 +- AOP 적용 필요 +- JWT를 헤더에서 가져와서 인증하는 부분이 계속해서 반복되는 것을 느껴 어노테이션으로 만들었지만 기존 메서드와 연결에서 어려움이 있어서 적용을 하지는 못했다. + +## 🌟느낀 점 +- 혼자 하는 프로젝트여서 협업에 큰 어려움이 없었지만, 다른 팀원들과 함께 하게 되면 버전 관리에 신경을 많이 써야할 것 같다. +- 모르고 있던(배웠으나 까먹은..?) 부분도 스스로 검색하고 다시 공부하며 빈 부분이 많이 채워졌다고 느꼈다. +- 지금까지 배운 내용이 다 들어있어서 뿌듯했다! From 4af432056df7eb3ecd6b6a4f305a37a5246f3855 Mon Sep 17 00:00:00 2001 From: hjoo <92681117+yhj1129@users.noreply.github.com> Date: Sun, 9 Apr 2023 23:41:22 +0900 Subject: [PATCH 27/27] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 48b52b7..a9774a4 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,13 @@ dependencies { } ``` +## 🗒️구현 요청 사항 +- 고객은 다수이다. +- 판매자는 한명이다. +- 고객은 여러건의 주문을 할 수 있다. +- 고객은 한번에 여러개의 상품을 주문할 수 있다. +- 고객은 상품 주문시에 개수를 선택할 수 있다. + ## 💡구현된 기능 ### 🙋🏻‍♀️사용자 기능 @@ -50,6 +57,10 @@ dependencies { **상세한 요청과 응답은 [api문서](https://github.com/yhj1129/Springboot-MetaMall-Project/blob/main/src/main/java/shop/mtcoding/metamall/api)를 확인** +## 🔗ER-Diagram +image + + ## 👩🏻‍🔧작성한 테스트 코드 - 레포지토리 쿼리 테스트 코드