From 37ab4da379e77f8aec7d0bd4a88370463463d22b Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:57:21 +0900 Subject: [PATCH 001/100] =?UTF-8?q?Feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EC=9A=94=EC=B2=AD=20DTO=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/roomescape/member/LoginRequest.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/roomescape/member/LoginRequest.java diff --git a/src/main/java/roomescape/member/LoginRequest.java b/src/main/java/roomescape/member/LoginRequest.java new file mode 100644 index 000000000..6966e571a --- /dev/null +++ b/src/main/java/roomescape/member/LoginRequest.java @@ -0,0 +1,9 @@ +package roomescape.member; + +public class LoginRequest { + private String email; + private String password; + + public String getEmail() { return email; } + public String getPassword() { return password; } +} From 636c329996802a8d7c46c8b122bcb0fa7bda5d2d Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:57:28 +0900 Subject: [PATCH 002/100] =?UTF-8?q?Feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B0=9C=EB=B0=9C=20=EB=B0=8F=20JWT=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EC=BF=A0=ED=82=A4=20=EB=B0=9C=EA=B8=89=20?= =?UTF-8?q?API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomescape/member/AuthController.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/roomescape/member/AuthController.java diff --git a/src/main/java/roomescape/member/AuthController.java b/src/main/java/roomescape/member/AuthController.java new file mode 100644 index 000000000..72462ab6a --- /dev/null +++ b/src/main/java/roomescape/member/AuthController.java @@ -0,0 +1,41 @@ +package roomescape.member; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class AuthController { + private final MemberDao memberDao; + // 32바이트 이상의 비밀키 설정 + private final String secretKey = "Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E="; + + public AuthController(MemberDao memberDao) { + this.memberDao = memberDao; + } + + @PostMapping("/login") + public ResponseEntity login(@RequestBody LoginRequest loginRequest, HttpServletResponse response) { + // 이미 구현되어 있는 findByEmailAndPassword 활용! + Member member = memberDao.findByEmailAndPassword(loginRequest.getEmail(), loginRequest.getPassword()); + + String accessToken = Jwts.builder() + .setSubject(member.getId().toString()) + .claim("name", member.getName()) + .claim("role", member.getRole()) + .signWith(Keys.hmacShaKeyFor(secretKey.getBytes())) + .compact(); + + Cookie cookie = new Cookie("token", accessToken); + cookie.setHttpOnly(true); + cookie.setPath("/"); + response.addCookie(cookie); + + return ResponseEntity.ok().build(); + } +} From aa182a63c968245736e8c3c8127d14cd511f6550 Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:57:38 +0900 Subject: [PATCH 003/100] =?UTF-8?q?Feat:=20JWT=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=ED=95=B4=EC=84=9D=20=EB=B0=8F=20Member=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EC=A3=BC=EC=9E=85=EC=9A=A9=20ArgumentReso?= =?UTF-8?q?lver=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/LoginMemberArgumentResolver.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/main/java/roomescape/member/LoginMemberArgumentResolver.java diff --git a/src/main/java/roomescape/member/LoginMemberArgumentResolver.java b/src/main/java/roomescape/member/LoginMemberArgumentResolver.java new file mode 100644 index 000000000..0f23fd42e --- /dev/null +++ b/src/main/java/roomescape/member/LoginMemberArgumentResolver.java @@ -0,0 +1,53 @@ +package roomescape.member; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver { + private final String secretKey = "Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E="; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + + return parameter.getParameterType().equals(Member.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); + Cookie[] cookies = request.getCookies(); + + if (cookies == null) { + throw new IllegalArgumentException("토큰 쿠키가 존재하지 않습니다."); + } + + String token = ""; + for (Cookie cookie : cookies) { + if ("token".equals(cookie.getName())) { + token = cookie.getValue(); + } + } + + // 토큰 파싱하여 회원 정보 추출 + Claims claims = Jwts.parserBuilder() + .setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes())) + .build() + .parseClaimsJws(token) + .getBody(); + + Long id = Long.parseLong(claims.getSubject()); + String name = claims.get("name", String.class); + String role = claims.get("role", String.class); + + return new Member(id, name, "", role); // 파싱된 정보로 임시 Member 객체 생성하여 반환 + } +} From 684129b8418f083044f558a335e72ad375bc40a0 Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:57:45 +0900 Subject: [PATCH 004/100] =?UTF-8?q?Feat:=20WebMvcConfigurer=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=EC=9D=84=20=ED=86=B5=ED=95=B4=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EC=95=84=EA=B7=9C=EB=A8=BC=ED=8A=B8=20=EB=A6=AC?= =?UTF-8?q?=EC=86=94=EB=B2=84=20=EC=B6=94=EA=B0=80=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/roomescape/WebMvcConfiguration.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/roomescape/WebMvcConfiguration.java diff --git a/src/main/java/roomescape/WebMvcConfiguration.java b/src/main/java/roomescape/WebMvcConfiguration.java new file mode 100644 index 000000000..fadfb0842 --- /dev/null +++ b/src/main/java/roomescape/WebMvcConfiguration.java @@ -0,0 +1,16 @@ +package roomescape; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import roomescape.member.LoginMemberArgumentResolver; + +import java.util.List; + +@Configuration +public class WebMvcConfiguration implements WebMvcConfigurer { + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new LoginMemberArgumentResolver()); + } +} From 444e69f121b9f90cd769bcadb2cb63f901a9174e Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:57:54 +0900 Subject: [PATCH 005/100] =?UTF-8?q?Refactor:=20=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=B9=98=ED=99=98=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=A7=80=EC=9B=90=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=98=88=EC=95=BD=20=EC=9A=94=EC=B2=AD=20DTO=20=EA=B0=80?= =?UTF-8?q?=EA=B3=B5=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/roomescape/reservation/ReservationRequest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/roomescape/reservation/ReservationRequest.java b/src/main/java/roomescape/reservation/ReservationRequest.java index 19f441246..e12033ea3 100644 --- a/src/main/java/roomescape/reservation/ReservationRequest.java +++ b/src/main/java/roomescape/reservation/ReservationRequest.java @@ -6,6 +6,13 @@ public class ReservationRequest { private Long theme; private Long time; + public ReservationRequest(String name, String date, Long theme, Long time) { + this.name = name; + this.date = date; + this.theme = theme; + this.time = time; + } + public String getName() { return name; } From e709d8b56b2f1f66a5155ae71a51eea8fe3f6fcc Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:58:01 +0900 Subject: [PATCH 006/100] =?UTF-8?q?Refactor:=20=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=EC=97=90=20ArgumentResolver=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=EB=B0=8F=20=EC=9D=B4=EB=A6=84=20=EC=B9=98?= =?UTF-8?q?=ED=99=98=20=EB=A1=9C=EC=A7=81=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/ReservationController.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/main/java/roomescape/reservation/ReservationController.java b/src/main/java/roomescape/reservation/ReservationController.java index b3bef3990..2fde76002 100644 --- a/src/main/java/roomescape/reservation/ReservationController.java +++ b/src/main/java/roomescape/reservation/ReservationController.java @@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import roomescape.member.Member; // 👈 새로 추가된 Member 도메인 패키지 임포트 확인! import java.net.URI; import java.util.List; @@ -26,14 +27,32 @@ public List list() { } @PostMapping("/reservations") - public ResponseEntity create(@RequestBody ReservationRequest reservationRequest) { - if (reservationRequest.getName() == null - || reservationRequest.getDate() == null - || reservationRequest.getTheme() == null - || reservationRequest.getTime() == null) { + public ResponseEntity create( + @RequestBody ReservationRequest reservationRequest, + Member loginMember + ) { + + String finalName = (reservationRequest.getName() != null && !reservationRequest.getName().isBlank()) + ? reservationRequest.getName() + : loginMember.getName(); + + + ReservationRequest finalRequest = new ReservationRequest( + finalName, + reservationRequest.getDate(), + reservationRequest.getTheme(), + reservationRequest.getTime() + ); + + + if (finalRequest.getName() == null + || finalRequest.getDate() == null + || finalRequest.getTheme() == null + || finalRequest.getTime() == null) { return ResponseEntity.badRequest().build(); } - ReservationResponse reservation = reservationService.save(reservationRequest); + + ReservationResponse reservation = reservationService.save(finalRequest); return ResponseEntity.created(URI.create("/reservations/" + reservation.getId())).body(reservation); } From 7e42eac5a178ea9fdd810b7602205eca9bb212da Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Mon, 29 Jun 2026 17:58:08 +0900 Subject: [PATCH 007/100] =?UTF-8?q?Test:=20=EC=9D=B8=EC=A6=9D=20=EB=B0=8F?= =?UTF-8?q?=20=EC=98=88=EC=95=BD=20=EC=9D=B4=EB=A6=84=20=EC=B9=98=ED=99=98?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=ED=99=95=EC=9D=B8=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=201,=202=EB=8B=A8=EA=B3=84=20=EC=9D=B8=EC=88=98=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/roomescape/MissionStepTest.java | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index 6add784bd..a6fa00d83 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -35,4 +35,55 @@ public class MissionStepTest { assertThat(token).isNotBlank(); } -} \ No newline at end of file + + + @Test + void 이단계() { + Map loginParams = new HashMap<>(); + loginParams.put("email", "admin@email.com"); + loginParams.put("password", "password"); + + ExtractableResponse loginResponse = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(loginParams) + .when().post("/login") + .then().statusCode(200) + .extract(); + + String token = loginResponse.headers().get("Set-Cookie").getValue().split(";")[0].split("=")[1]; + + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", "2026-07-01"); + params.put("time", "4"); + params.put("theme", "1"); + + ExtractableResponse adminResponse = RestAssured.given().log().all() + .body(params) + .cookie("token", token) + .contentType(ContentType.JSON) + .post("/reservations") + .then().log().all() + .extract(); + + assertThat(adminResponse.statusCode()).isEqualTo(201); + assertThat(adminResponse.jsonPath().getString("name")).isEqualTo("브라운"); + + + Map userParams = new HashMap<>(); + userParams.put("date", "2026-07-02"); + userParams.put("time", "4"); + userParams.put("theme", "1"); + + ExtractableResponse userResponse = RestAssured.given().log().all() + .body(userParams) + .cookie("token", token) + .contentType(ContentType.JSON) + .post("/reservations") + .then().log().all() + .extract(); + + assertThat(userResponse.statusCode()).isEqualTo(201); + assertThat(userResponse.jsonPath().getString("name")).isEqualTo("어드민"); + } +} From da54f461ae3d2e55167a7b61e90209a25b440091 Mon Sep 17 00:00:00 2001 From: haeun92e0 Date: Wed, 1 Jul 2026 23:02:04 +0900 Subject: [PATCH 008/100] =?UTF-8?q?Docs:=20=EB=B3=B5=EC=8A=B5=EC=9A=A9=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/roomescape/PageController.java | 2 +- .../java/roomescape/WebMvcConfiguration.java | 1 + .../roomescape/member/AuthController.java | 10 ++++---- .../member/LoginMemberArgumentResolver.java | 19 ++++++++------ .../java/roomescape/member/LoginRequest.java | 2 +- .../roomescape/member/MemberController.java | 10 ++++---- .../java/roomescape/member/MemberDao.java | 11 ++++---- .../java/roomescape/member/MemberRequest.java | 2 +- .../java/roomescape/member/MemberService.java | 1 + .../reservation/ReservationController.java | 6 ++--- .../reservation/ReservationDao.java | 13 +++++----- .../reservation/ReservationService.java | 5 ++-- src/main/java/roomescape/theme/ThemeDao.java | 4 +-- .../java/roomescape/time/TimeService.java | 6 ++--- src/main/resources/schema.sql | 25 ++++++++++--------- 15 files changed, 63 insertions(+), 54 deletions(-) diff --git a/src/main/java/roomescape/PageController.java b/src/main/java/roomescape/PageController.java index ac8ef9408..d564274e1 100644 --- a/src/main/java/roomescape/PageController.java +++ b/src/main/java/roomescape/PageController.java @@ -4,7 +4,7 @@ import org.springframework.web.bind.annotation.GetMapping; @Controller -public class PageController { +public class PageController {//화면을 보여주는 api 컨트롤러 @GetMapping("/admin") public String admin() { return "admin/index"; diff --git a/src/main/java/roomescape/WebMvcConfiguration.java b/src/main/java/roomescape/WebMvcConfiguration.java index fadfb0842..d4465ad0b 100644 --- a/src/main/java/roomescape/WebMvcConfiguration.java +++ b/src/main/java/roomescape/WebMvcConfiguration.java @@ -14,3 +14,4 @@ public void addArgumentResolvers(List resolvers) resolvers.add(new LoginMemberArgumentResolver()); } } +//LoginMemberArgumentResolver을 스프링 MVC에 ㄷ등록해서 사용할 수 있게 해줌 diff --git a/src/main/java/roomescape/member/AuthController.java b/src/main/java/roomescape/member/AuthController.java index 72462ab6a..214f2b49b 100644 --- a/src/main/java/roomescape/member/AuthController.java +++ b/src/main/java/roomescape/member/AuthController.java @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -public class AuthController { +public class AuthController { //로그인 관련 요청을 처리 private final MemberDao memberDao; // 32바이트 이상의 비밀키 설정 private final String secretKey = "Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E="; @@ -23,19 +23,19 @@ public AuthController(MemberDao memberDao) { public ResponseEntity login(@RequestBody LoginRequest loginRequest, HttpServletResponse response) { // 이미 구현되어 있는 findByEmailAndPassword 활용! Member member = memberDao.findByEmailAndPassword(loginRequest.getEmail(), loginRequest.getPassword()); - + //JWT 만들기 String accessToken = Jwts.builder() .setSubject(member.getId().toString()) .claim("name", member.getName()) .claim("role", member.getRole()) - .signWith(Keys.hmacShaKeyFor(secretKey.getBytes())) + .signWith(Keys.hmacShaKeyFor(secretKey.getBytes())) //비밀키로 JWT에 서명 .compact(); - Cookie cookie = new Cookie("token", accessToken); + Cookie cookie = new Cookie("token", accessToken); //쿠키 하나를 만듦 cookie.setHttpOnly(true); cookie.setPath("/"); response.addCookie(cookie); - return ResponseEntity.ok().build(); + return ResponseEntity.ok().build(); // 로그인 성공으로 200 반환 } } diff --git a/src/main/java/roomescape/member/LoginMemberArgumentResolver.java b/src/main/java/roomescape/member/LoginMemberArgumentResolver.java index 0f23fd42e..7803ea4b8 100644 --- a/src/main/java/roomescape/member/LoginMemberArgumentResolver.java +++ b/src/main/java/roomescape/member/LoginMemberArgumentResolver.java @@ -11,6 +11,7 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; +//컨트롤러의 매개변수를 자동으로 만들어주는 클래스 public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver { private final String secretKey = "Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E="; @@ -18,13 +19,13 @@ public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolve public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterType().equals(Member.class); - } + }//컨트롤러의 매개변수가 member 타입이면 처리할 수 있다는 뜻 - @Override + @Override //Member객체를 실제로 만드는 함수 public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); - Cookie[] cookies = request.getCookies(); + HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); //현재 HTTP 요청 가져오기 + Cookie[] cookies = request.getCookies(); //쿠키 가져오기 if (cookies == null) { throw new IllegalArgumentException("토큰 쿠키가 존재하지 않습니다."); @@ -32,8 +33,8 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m String token = ""; for (Cookie cookie : cookies) { - if ("token".equals(cookie.getName())) { - token = cookie.getValue(); + if ("token".equals(cookie.getName())) {//이름이 token인 쿠키 찾기 + token = cookie.getValue(); //JWT 문자열 저장 } } @@ -41,9 +42,9 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m Claims claims = Jwts.parserBuilder() .setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes())) .build() - .parseClaimsJws(token) + .parseClaimsJws(token)//JWT 해석 .getBody(); - + //정보 꺼내기 Long id = Long.parseLong(claims.getSubject()); String name = claims.get("name", String.class); String role = claims.get("role", String.class); @@ -51,3 +52,5 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m return new Member(id, name, "", role); // 파싱된 정보로 임시 Member 객체 생성하여 반환 } } +//브라우저가 보낸 JWT 쿠키를 읽어서 그 안에 저장된 회원 정보를 Member 객체로 복원한 뒤, 컨트롤러의 Member loginMember 매개변수에 자동으로 +//넣어주는 역할 diff --git a/src/main/java/roomescape/member/LoginRequest.java b/src/main/java/roomescape/member/LoginRequest.java index 6966e571a..36cef44ae 100644 --- a/src/main/java/roomescape/member/LoginRequest.java +++ b/src/main/java/roomescape/member/LoginRequest.java @@ -1,6 +1,6 @@ package roomescape.member; -public class LoginRequest { +public class LoginRequest {// 로그인 요청 private String email; private String password; diff --git a/src/main/java/roomescape/member/MemberController.java b/src/main/java/roomescape/member/MemberController.java index 881ae5e0d..64e6143f7 100644 --- a/src/main/java/roomescape/member/MemberController.java +++ b/src/main/java/roomescape/member/MemberController.java @@ -19,19 +19,19 @@ public MemberController(MemberService memberService) { this.memberService = memberService; } - @PostMapping("/members") + @PostMapping("/members") //회원가입 public ResponseEntity createMember(@RequestBody MemberRequest memberRequest) { MemberResponse member = memberService.createMember(memberRequest); return ResponseEntity.created(URI.create("/members/" + member.getId())).body(member); } - @PostMapping("/logout") + @PostMapping("/logout") //로그아웃 시 public ResponseEntity logout(HttpServletResponse response) { - Cookie cookie = new Cookie("token", ""); + Cookie cookie = new Cookie("token", ""); //새로운 쿠키 만들기 cookie.setHttpOnly(true); cookie.setPath("/"); - cookie.setMaxAge(0); - response.addCookie(cookie); + cookie.setMaxAge(0); //유효시간 0초로 바꾸기 > 즉시 만료 + response.addCookie(cookie);// 기존 token을 새로운 쿠키로 덮어씀 return ResponseEntity.ok().build(); } } diff --git a/src/main/java/roomescape/member/MemberDao.java b/src/main/java/roomescape/member/MemberDao.java index 81f77f4cd..b81eac42a 100644 --- a/src/main/java/roomescape/member/MemberDao.java +++ b/src/main/java/roomescape/member/MemberDao.java @@ -8,12 +8,12 @@ @Repository public class MemberDao { private JdbcTemplate jdbcTemplate; - + //의존성 주입 public MemberDao(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } - public Member save(Member member) { + public Member save(Member member) { //회원가입할 때 실행됨. 회원가입 정보를 DB에 저장하는 함수 KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(connection -> { var ps = connection.prepareStatement("INSERT INTO member(name, email, password, role) VALUES (?, ?, ?, ?)", new String[]{"id"}); @@ -23,10 +23,11 @@ public Member save(Member member) { ps.setString(4, member.getRole()); return ps; }, keyHolder); - + //회원 가입 끝, 새로운 Member 객체를 만들어 반환해줌 return new Member(keyHolder.getKey().longValue(), member.getName(), member.getEmail(), "USER"); } + //이메일과 패스워드로 로그인 할 회원을 찾음 public Member findByEmailAndPassword(String email, String password) { return jdbcTemplate.queryForObject( "SELECT id, name, email, role FROM member WHERE email = ? AND password = ?", @@ -37,9 +38,9 @@ public Member findByEmailAndPassword(String email, String password) { rs.getString("role") ), email, password - ); + );//로그인한 사람의 정보를 서버도 알아야 하기 때문에 member 객체 생성 } - + //이름으로 회원 찾기 public Member findByName(String name) { return jdbcTemplate.queryForObject( "SELECT id, name, email, role FROM member WHERE name = ?", diff --git a/src/main/java/roomescape/member/MemberRequest.java b/src/main/java/roomescape/member/MemberRequest.java index cafb79f14..b6bba1dcf 100644 --- a/src/main/java/roomescape/member/MemberRequest.java +++ b/src/main/java/roomescape/member/MemberRequest.java @@ -1,6 +1,6 @@ package roomescape.member; -public class MemberRequest { +public class MemberRequest { //회원가입 요청 private String name; private String email; private String password; diff --git a/src/main/java/roomescape/member/MemberService.java b/src/main/java/roomescape/member/MemberService.java index ccaa8cba5..4b455efd1 100644 --- a/src/main/java/roomescape/member/MemberService.java +++ b/src/main/java/roomescape/member/MemberService.java @@ -11,6 +11,7 @@ public MemberService(MemberDao memberDao) { } public MemberResponse createMember(MemberRequest memberRequest) { + //회원가입 요청을 받아서 회원을 만들고 응답데이터 반환 Member member = memberDao.save(new Member(memberRequest.getName(), memberRequest.getEmail(), memberRequest.getPassword(), "USER")); return new MemberResponse(member.getId(), member.getName(), member.getEmail()); } diff --git a/src/main/java/roomescape/reservation/ReservationController.java b/src/main/java/roomescape/reservation/ReservationController.java index 2fde76002..aed6fe2d2 100644 --- a/src/main/java/roomescape/reservation/ReservationController.java +++ b/src/main/java/roomescape/reservation/ReservationController.java @@ -21,7 +21,7 @@ public ReservationController(ReservationService reservationService) { this.reservationService = reservationService; } - @GetMapping("/reservations") + @GetMapping("/reservations") //예약 목록 반환 public List list() { return reservationService.findAll(); } @@ -29,14 +29,14 @@ public List list() { @PostMapping("/reservations") public ResponseEntity create( @RequestBody ReservationRequest reservationRequest, - Member loginMember + Member loginMember //현재 로그인한 회원 ) { String finalName = (reservationRequest.getName() != null && !reservationRequest.getName().isBlank()) ? reservationRequest.getName() : loginMember.getName(); - + // 예약 요청에 이름이 있으면 그 이름으로, 없으면 로그인한 회원 이름으로 ReservationRequest finalRequest = new ReservationRequest( finalName, reservationRequest.getDate(), diff --git a/src/main/java/roomescape/reservation/ReservationDao.java b/src/main/java/roomescape/reservation/ReservationDao.java index a4972430c..08eaedf66 100644 --- a/src/main/java/roomescape/reservation/ReservationDao.java +++ b/src/main/java/roomescape/reservation/ReservationDao.java @@ -18,9 +18,10 @@ public class ReservationDao { public ReservationDao(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } + //의존성 주입 - public List findAll() { - return jdbcTemplate.query( + public List findAll() {//예약 정보 전부 가져오기 + return jdbcTemplate.query(//time과 theme 테이블 조인 "SELECT r.id AS reservation_id, r.name as reservation_name, r.date as reservation_date, " + "t.id AS theme_id, t.name AS theme_name, t.description AS theme_description, " + "ti.id AS time_id, ti.time_value AS time_value " + @@ -28,7 +29,7 @@ public List findAll() { "JOIN theme t ON r.theme_id = t.id " + "JOIN time ti ON r.time_id = ti.id", - (rs, rowNum) -> new Reservation( + (rs, rowNum) -> new Reservation(//reservation 객체로 바꿈 rs.getLong("reservation_id"), rs.getString("reservation_name"), rs.getString("reservation_date"), @@ -43,7 +44,7 @@ public List findAll() { ))); } - public Reservation save(ReservationRequest reservationRequest) { + public Reservation save(ReservationRequest reservationRequest) {//예약 생성 KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(connection -> { PreparedStatement ps = connection.prepareStatement("INSERT INTO reservation(date, name, theme_id, time_id) VALUES (?, ?, ?, ?)", new String[]{"id"}); @@ -66,7 +67,7 @@ public Reservation save(ReservationRequest reservationRequest) { keyHolder.getKey().longValue(), reservationRequest.getName(), reservationRequest.getDate(), - time, + time, //timeid가 아닌 time이 들어가기 때문에 theme ); } @@ -74,7 +75,7 @@ public Reservation save(ReservationRequest reservationRequest) { public void deleteById(Long id) { jdbcTemplate.update("DELETE FROM reservation WHERE id = ?", id); } - + //날짜와 테마로 예약 찾기 public List findReservationsByDateAndTheme(String date, Long themeId) { return jdbcTemplate.query( "SELECT r.id AS reservation_id, r.name as reservation_name, r.date as reservation_date, " + diff --git a/src/main/java/roomescape/reservation/ReservationService.java b/src/main/java/roomescape/reservation/ReservationService.java index bd3313328..f63a916c5 100644 --- a/src/main/java/roomescape/reservation/ReservationService.java +++ b/src/main/java/roomescape/reservation/ReservationService.java @@ -13,7 +13,7 @@ public ReservationService(ReservationDao reservationDao) { } public ReservationResponse save(ReservationRequest reservationRequest) { - Reservation reservation = reservationDao.save(reservationRequest); + Reservation reservation = reservationDao.save(reservationRequest); //db에 저장됨 return new ReservationResponse(reservation.getId(), reservationRequest.getName(), reservation.getTheme().getName(), reservation.getDate(), reservation.getTime().getValue()); } @@ -26,5 +26,6 @@ public List findAll() { return reservationDao.findAll().stream() .map(it -> new ReservationResponse(it.getId(), it.getName(), it.getTheme().getName(), it.getDate(), it.getTime().getValue())) .toList(); - } + }// dao에서 reservation list를 반환해주기 때문에 그 예약 하나하나를 stream으로 처리해서 reservationResponse를 만든다. + //마지막에 toList()로 ReservationResponse도 리스트로 만들어줌 } diff --git a/src/main/java/roomescape/theme/ThemeDao.java b/src/main/java/roomescape/theme/ThemeDao.java index 945341d8d..5808bcd16 100644 --- a/src/main/java/roomescape/theme/ThemeDao.java +++ b/src/main/java/roomescape/theme/ThemeDao.java @@ -15,7 +15,7 @@ public ThemeDao(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } - public List findAll() { + public List findAll() {//테마 전부 가져오기 return jdbcTemplate.query("SELECT * FROM theme where deleted = false", (rs, rowNum) -> new Theme( rs.getLong("id"), rs.getString("name"), @@ -23,7 +23,7 @@ public List findAll() { )); } - public Theme save(Theme theme) { + public Theme save(Theme theme) {//새로운 테마 저장 KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(connection -> { var ps = connection.prepareStatement("INSERT INTO theme(name, description) VALUES (?, ?)", new String[]{"id"}); diff --git a/src/main/java/roomescape/time/TimeService.java b/src/main/java/roomescape/time/TimeService.java index 7d0cb9b09..905161fe1 100644 --- a/src/main/java/roomescape/time/TimeService.java +++ b/src/main/java/roomescape/time/TimeService.java @@ -17,10 +17,10 @@ public TimeService(TimeDao timeDao, ReservationDao reservationDao) { } public List getAvailableTime(String date, Long themeId) { - List reservations = reservationDao.findByDateAndThemeId(date, themeId); - List