-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
부산대 BE_김상해 3주차 과제 (2단계) #354
Open
gobad820
wants to merge
26
commits into
kakao-tech-campus-2nd-step2:gobad820
Choose a base branch
from
gobad820:step2
base: gobad820
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
d25c602
feat: Week2 파일 복사
gobad820 795e65f
feat: Week2 파일 복사
gobad820 b18fc19
refactor: 모델 엔티티로 변경
gobad820 3bc43b3
chore: jpa 의존성 추가
gobad820 32cfade
refactor: JpaRepository로 변경
gobad820 05322a8
feat: Product Optional<Product>로 변경
gobad820 95706f3
feat: Product Optional<Product>로 변경
gobad820 2dd8752
refactor: datasource url 변경
gobad820 8a2c99e
feat: JpaRepository Test 생성
gobad820 3dcce74
feat: test용 application 생성
gobad820 36c8f4c
chore: 파일 포매팅
gobad820 17623dc
feat: 연관 관계 매핑 추가
gobad820 c278615
feat: Repository에서 find 시 참조 사용
gobad820 3e530a5
feat: 매개변수 외래키에서 참조로 변경
gobad820 e3bf5d8
chore: import 추가 및 포매팅
gobad820 2dc9350
feat: 매개변수 외래 키에서 참조로 변경
gobad820 db2b0f7
chore: 포매팅 및 주석 추가
gobad820 6a490d5
feat: gitignore 생성
gobad820 d9757a0
fix: href 링크 업데이트
gobad820 73a65f3
chore: 변수명 변경 및 import 수정
gobad820 00231b0
feat(model): equals, hashCode 오버라이드 메소드 추가
gobad820 47e53bf
feat: findByName 메소드 추가
gobad820 1d165c1
fix: updateProduct 수정
gobad820 ab77779
feat: SetUp 메소드 추가
gobad820 8bd8807
feat: ProductController 뷰 템플릿 리턴
gobad820 4387a1f
feat: READEME step2 추가
gobad820 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,3 +38,4 @@ out/ | |
|
||
### Mac OS ### | ||
.DS_Store | ||
/src/test/java/gift/study/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
# spring-gift-jpa | ||
# spring-gift-jpa | ||
|
||
- [x] Member, Wish 연관 관계 매핑 | ||
- [x] Product, Wish 연관 관계 매핑 | ||
- [x] MemberRepositoryTest | ||
- [x] WishRepositoryTest | ||
- [x] ProductRepositoryTest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package gift.annotation; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Documented | ||
public @interface LoginMember { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package gift.controller; | ||
|
||
import gift.model.Member; | ||
import gift.service.MemberService; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
|
||
@Controller | ||
@RequestMapping("/members") | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
public MemberController(MemberService memberService) { | ||
this.memberService = memberService; | ||
} | ||
|
||
@PostMapping("/register") | ||
public ResponseEntity<Map<String, Object>> register(@RequestBody Member member) { | ||
return memberService.registerMember(member) | ||
.map(token -> { // Optional<String>을 mapping -> isPresent면 map 안 실행 // 매개변수 token으로 | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("message", "Member registered successfully"); | ||
response.put("token", token); // 생성된 토큰도 같이 보내준다. | ||
return new ResponseEntity<>(response, HttpStatus.OK); | ||
}) | ||
.orElseGet(() -> { // isEmpty | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("message", "Registration failed"); | ||
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR); | ||
Comment on lines
+34
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오류가 났을때
무조건적인 500 에러보다는 대략적인 오류코드나 메세지를 전달해주는것이 좋아요. |
||
}); | ||
} | ||
|
||
@PostMapping("/login") | ||
public ResponseEntity<Map<String, Object>> login(@RequestBody Member member) { | ||
return memberService.login(member.getEmail(), member.getPassword()) | ||
.map(token -> { // 토큰이 리턴 -> 정상 로그인 됨 | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("token", token); | ||
return new ResponseEntity<>(response, HttpStatus.OK); | ||
}) | ||
.orElseGet(() -> { // 토큰 리턴이 안됨 -> 로그인 안됨 | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("message", "Invalid email or password"); | ||
return new ResponseEntity<>(response, HttpStatus.FORBIDDEN); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package gift.controller; | ||
|
||
import gift.exception.ProductNotFoundException; | ||
import gift.model.Product; | ||
import gift.service.ProductService; | ||
import jakarta.validation.Valid; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.ui.Model; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.ModelAttribute; | ||
import org.springframework.web.bind.annotation.PatchMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
|
||
@Controller | ||
public class ProductController { | ||
|
||
private final ProductService productService; | ||
|
||
public ProductController(ProductService productService) { | ||
this.productService = productService; | ||
} | ||
|
||
@GetMapping("/") | ||
public String getAllMyProducts(Model model) { | ||
var productList = productService.getAllProducts(); | ||
model.addAttribute("productList", productList); | ||
return "getproducts"; | ||
} | ||
|
||
@GetMapping("/test") | ||
public ResponseEntity<Map<String, Object>> getAllProducts() { | ||
List<Product> products = productService.getAllProducts(); | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("message", "All products retrieved successfully."); | ||
response.put("products", products); | ||
return ResponseEntity.ok(response); | ||
} | ||
|
||
@GetMapping("/{id}") | ||
public String getProductById(@PathVariable(name = "id") Long id, Model model) { | ||
Map<String, Object> response = new HashMap<>(); | ||
try { | ||
Product product = productService.getProductById(id); | ||
model.addAttribute("productDto", product); | ||
return "getproducts"; | ||
} catch (ProductNotFoundException ex) { | ||
response.put("message", ex.getMessage()); | ||
model.addAttribute("errorMessage", response.get("message")); | ||
return "getproducts"; | ||
} | ||
} | ||
|
||
@GetMapping("/product/add") | ||
public String showAddProductForm(Model model) { | ||
model.addAttribute("product", new Product()); | ||
return "addproductform"; | ||
} | ||
|
||
@PostMapping("/product/add") | ||
public String createProduct(@Valid @ModelAttribute(name = "product") Product product) { | ||
productService.createProduct(product); | ||
return "redirect:/"; | ||
} | ||
|
||
@GetMapping(value = "/product/update/{id}") | ||
public String showUPdateProductForm(@PathVariable("id") Long id, Model model) { | ||
var product = productService.getProductById(id); | ||
model.addAttribute("product", product); | ||
return "updateproductform"; | ||
} | ||
|
||
@PostMapping(value = "/product/update") | ||
public String updateProduct(@Valid @ModelAttribute(name = "product") Product product) { | ||
var updatedProduct = productService.updateProduct(product); | ||
return "redirect:/"; | ||
} | ||
|
||
@PatchMapping("/{id}") | ||
public ResponseEntity<Map<String, Object>> patchProduct(@PathVariable Long id, | ||
@RequestBody Map<String, Object> updates) { | ||
Map<String, Object> response = new HashMap<>(); | ||
if (productService.patchProduct(id, updates) != null) { | ||
Product updatedProduct = productService.getProductById(id); | ||
response.put("message", "Product patched successfully."); | ||
response.put("product", updatedProduct); | ||
return ResponseEntity.ok(response); | ||
} | ||
response.put("message", "Failed to patch product."); | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); | ||
} | ||
|
||
@PatchMapping | ||
public ResponseEntity<Map<String, Object>> patchProducts( | ||
@RequestBody List<Map<String, Object>> updatesList) { | ||
List<Optional<Product>> updatedProducts = productService.patchProducts(updatesList); | ||
Map<String, Object> response = new HashMap<>(); | ||
int originalCount = updatesList.size(); | ||
int updateCount = updatedProducts.size(); | ||
|
||
response.put("updatedProducts", updatedProducts); | ||
|
||
if (updateCount == originalCount) { | ||
response.put("message", "All products patched successfully."); | ||
return ResponseEntity.ok(response); | ||
} | ||
|
||
if (updateCount > 0) { | ||
response.put("message", "Some products patched successfully."); | ||
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT).body(response); | ||
} | ||
|
||
response.put("message", "No products patched."); | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); | ||
} | ||
|
||
@GetMapping("/product/delete/{id}") | ||
public String showDeleteProductForm(@PathVariable("id") Long id, Model model) { | ||
if (!productService.deleteProduct(id)) { | ||
model.addAttribute("errorMessage", "잘못됨"); | ||
} | ||
return "redirect:/"; | ||
} | ||
|
||
@DeleteMapping("/{id}") | ||
public ResponseEntity<Map<String, Object>> deleteProduct(@PathVariable Long id) { | ||
boolean success = productService.deleteProduct(id); | ||
Map<String, Object> response = new HashMap<>(); | ||
if (success) { | ||
response.put("message", "Product deleted successfully."); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
response.put("message", "Failed to delete product."); | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package gift.controller; | ||
|
||
import gift.annotation.LoginMember; | ||
import gift.model.Member; | ||
import gift.model.Wish; | ||
import gift.service.WishService; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequestMapping("/wishes") | ||
public class WishController { | ||
|
||
private final WishService wishService; | ||
|
||
public WishController(WishService wishService) { | ||
this.wishService = wishService; | ||
} | ||
|
||
@GetMapping | ||
public ResponseEntity<Map<String, Object>> getWishes(@LoginMember Member member) { | ||
List<Wish> wishes = wishService.getWishesByMember(member); | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("wishes", wishes); | ||
return new ResponseEntity<>(response, HttpStatus.OK); | ||
} | ||
|
||
@PostMapping | ||
public ResponseEntity<Map<String, Object>> addWish(@RequestBody Wish wish, | ||
@LoginMember Member member) { | ||
wish.setMemberId(member.getId()); | ||
Wish savedWish = wishService.addWish(wish); | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("wish", savedWish); | ||
return new ResponseEntity<>(response, HttpStatus.OK); | ||
} | ||
|
||
@DeleteMapping("/{id}") | ||
public ResponseEntity<Map<String, Object>> removeWish(@PathVariable Long id, | ||
@LoginMember Member member) { | ||
boolean removed = wishService.removeWish(id, member); | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("removed", removed); | ||
return new ResponseEntity<>(response, HttpStatus.OK); | ||
} | ||
|
||
@GetMapping("/{id}") | ||
public ResponseEntity<Map<String, Object>> getWishesById(@PathVariable Long productId, | ||
@LoginMember Member member) { | ||
List<Wish> wishes = wishService.getWishesByMember(member); | ||
Map<String, Object> response = new HashMap<>(); | ||
response.put("wishes", wishes); | ||
return new ResponseEntity<>(response, HttpStatus.OK); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package gift.exception; | ||
|
||
public class ForbiddenException extends RuntimeException { | ||
|
||
public ForbiddenException(String message) { | ||
super(message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package gift.exception; | ||
|
||
public class ForbiddenWordException extends RuntimeException { | ||
|
||
public ForbiddenWordException(String message) { | ||
super(message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package gift.exception; | ||
|
||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.util.NoSuchElementException; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
@RestControllerAdvice | ||
public class GiftExceptionHandler extends RuntimeException { | ||
|
||
@ResponseStatus(value = HttpStatus.NOT_FOUND) | ||
@ExceptionHandler(NoSuchElementException.class) | ||
public void ResourceNotFoundException(NoSuchElementException e, | ||
HttpServletResponse response) throws IOException { | ||
response.sendRedirect("/"); | ||
} | ||
|
||
@ResponseStatus(value = HttpStatus.NOT_FOUND) | ||
@ExceptionHandler(IllegalArgumentException.class) | ||
public void handleProductNameException(IllegalArgumentException e, | ||
HttpServletResponse response) throws IOException { | ||
response.sendRedirect("redirect:/product/add/form"); | ||
} | ||
|
||
@ResponseStatus(value = HttpStatus.FORBIDDEN) | ||
@ExceptionHandler(ForbiddenException.class) | ||
public final ResponseEntity<Object> handleForbiddenException(ForbiddenException e) { | ||
return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN); | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게 로그인 처리해야하는 부분은 다른 개발자를 위해서 샘플로 README.md 파일에 추가해주는게 좋아요.