-
Notifications
You must be signed in to change notification settings - Fork 80
[그리디] 서현진 Spring JPA (2차) 4, 5, 6 단계 미션 제출합니다. #209
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
Open
nonactress
wants to merge
49
commits into
next-step:nonactress
Choose a base branch
from
nonactress:hyeonjin3
base: nonactress
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
49 commits
Select commit
Hold shift + click to select a range
29a3411
feat : 일단계 테스트 통과
nonactress 76e20ba
feat(dao) : 이메일로 멤버 찾기
nonactress 6884888
feat(MemberController) : 회원 조회
nonactress b994a63
feat : 2단계 통과~!!!!
nonactress 9234df4
feat : AdminInterceptor 생성
nonactress 103e6bb
feat(webConfig) : admin인터셉터 추가
nonactress ecd0c7f
fix : 개행정리
nonactress 334327e
fix : 개행정리2
nonactress eeb4f66
fix : 패키지 정리
nonactress a75257b
fix : 1단계 login 쿠키 설정 및 tokenResponse dto 제거
nonactress f95bdc5
feat : time 엔티티로 수정 및 repository 생성
nonactress c1610e8
fix(Time) : 서비스에서 timerepository 사용 리팩토링
nonactress aa8870e
fix(Theme) : 컨트롤러에서 DAO -> Repository 사용
nonactress 9f54ac5
fix(All)
nonactress a674fa5
fix(All) : reservation.save 오버로딩 및 영속성 관리 하여 에러 수정
nonactress f9f63d1
refactor(Reservaiton) : 예약 조회 기능 생성
nonactress 5ee3e74
feat : waiting 엔티티 생성
nonactress cc28fde
feat : WaitingRepository 생성
nonactress b5cca3b
fix : ReservationService 리팩토링
nonactress 9deeb22
feat : waiting dto 생성
nonactress 7742db7
feat : WaitingService,controller 생성
nonactress 0812bd7
개행정리
nonactress 8f084a7
feat : 예외 처리
nonactress 4876179
fix : WaitingRepository 스프링 data jpa 사용
nonactress 0f3aadf
fix : ReservationRepository 스프링 data jpa 사용
nonactress 7a12ebf
fix : MemberRepository 스프링 data jpa 사용
nonactress b05b545
fix : ThemeRepository 스프링 data jpa 사용
nonactress e83a263
fix : TimeRepository 스프링 data jpa 사용
nonactress 916af1e
rename : advice 패키지 -> exception 패키지
nonactress 48a6984
fix : theme 생성자
nonactress 659c17b
fix : 예외 처리
nonactress f4f58e9
fix : 예외 처리2
nonactress 4c51bea
fix : authService 생성 및 상태코드 변경
nonactress db04811
refactor : 리포맷 적용 && 안쓰는 메소드 삭제
nonactress 1ca9fa1
refactor : isDeleted->delete
nonactress 494fffe
refactor : readOnly = true 적용
nonactress 0f655d2
필드 값 final로 변경
nonactress 5ce1144
refactor(themeService) : 클래스 단위 트랜젝션 적용
nonactress eecfe3a
refactor(themeService) : 중복된 삭제 로직 정리
nonactress bd4201c
refactor(themeService) : 중복된 삭제 로직 정리
nonactress d4fc462
refactor(all) : 안쓰는 import 과 메소드 정리
nonactress fd5d1a5
refactor(all) : 안쓰는 import 과 메소드 정리
nonactress 7c953c7
refactor(all) : 안쓰는 import 과 메소드 정리2
nonactress 55bc1b7
del : 로그 관련 설정
52a80f2
fix : 로그인 관련 401 상태코드로 변경
nonactress ba0194b
fix : transactional 적용
nonactress 0e1576d
fix : 메소드 분리
nonactress faf90f5
fix : 멤버와 관리자 로직 분리 조건
nonactress 137c138
fix : 소프트 딜리트 관련 삭제 방어코드
nonactress 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 hidden or 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 was deleted.
Oops, something went wrong.
This file contains hidden or 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,11 @@ | ||
| package roomescape.auth; | ||
|
|
||
| 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) | ||
| public @interface AuthMember { | ||
| } |
This file contains hidden or 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,44 @@ | ||
| package roomescape.auth; | ||
|
|
||
| import jakarta.servlet.http.Cookie; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import roomescape.exception.AuthenticationException; | ||
| import roomescape.infrastructure.JwtTokenProvider; | ||
| import roomescape.member.Member; | ||
| import roomescape.member.MemberService; | ||
|
|
||
| @Service | ||
| @Transactional(readOnly = true) | ||
| public class AuthService { | ||
| private final JwtTokenProvider jwtTokenProvider; | ||
| private final MemberService memberService; | ||
|
|
||
| public AuthService(JwtTokenProvider jwtTokenProvider, MemberService memberService) { | ||
| this.jwtTokenProvider = jwtTokenProvider; | ||
| this.memberService = memberService; | ||
| } | ||
|
|
||
| public Member extractMember(HttpServletRequest request) { | ||
| String token = extractTokenFromCookie(request); | ||
|
|
||
| if (!jwtTokenProvider.validateToken(token)) { | ||
| throw new AuthenticationException("인증되지 않은 사용자입니다."); | ||
| } | ||
|
|
||
| return memberService.findByToken(token); | ||
| } | ||
|
|
||
| private String extractTokenFromCookie(HttpServletRequest request) { | ||
| Cookie[] cookies = request.getCookies(); | ||
| if (cookies != null) { | ||
| for (Cookie cookie : cookies) { | ||
| if ("token".equals(cookie.getName())) { | ||
| return cookie.getValue(); | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| } |
8 changes: 8 additions & 0 deletions
8
src/main/java/roomescape/exception/AuthenticationException.java
This file contains hidden or 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 roomescape.exception; | ||
|
|
||
| public class AuthenticationException extends RuntimeException { | ||
|
|
||
| public AuthenticationException(String message) { | ||
| super(message); | ||
| } | ||
| } |
This file contains hidden or 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,4 @@ | ||
| package roomescape.exception; | ||
|
|
||
| public record ErrorResponse(String message) { | ||
| } |
28 changes: 28 additions & 0 deletions
28
src/main/java/roomescape/exception/GlobalExceptionHandler.java
This file contains hidden or 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,28 @@ | ||
| package roomescape.exception; | ||
|
|
||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.ControllerAdvice; | ||
| import org.springframework.web.bind.annotation.ExceptionHandler; | ||
|
|
||
| @ControllerAdvice | ||
| public class GlobalExceptionHandler { | ||
|
|
||
| @ExceptionHandler(IllegalArgumentException.class) | ||
| public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException e) { | ||
| return ResponseEntity.badRequest() | ||
| .body(new ErrorResponse(e.getMessage())); | ||
| } | ||
|
|
||
| @ExceptionHandler(AuthenticationException.class) | ||
| public ResponseEntity<String> handleAuthenticationException(AuthenticationException e) { | ||
| return ResponseEntity.status(HttpStatus.UNAUTHORIZED) | ||
| .body(e.getMessage()); | ||
| } | ||
|
|
||
| @ExceptionHandler(Exception.class) | ||
| public ResponseEntity<ErrorResponse> handleException(Exception e) { | ||
| return ResponseEntity.internalServerError() | ||
| .body(new ErrorResponse("오류가 발생했습니다.")); | ||
| } | ||
| } |
103 changes: 103 additions & 0 deletions
103
src/main/java/roomescape/infrastructure/DataInitializer.java
This file contains hidden or 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,103 @@ | ||
| package roomescape.infrastructure; | ||
|
|
||
| import org.springframework.boot.CommandLineRunner; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import roomescape.member.Member; | ||
| import roomescape.member.MemberRepository; | ||
| import roomescape.reservation.Reservation; | ||
| import roomescape.reservation.ReservationRepository; | ||
| import roomescape.theme.Theme; | ||
| import roomescape.theme.ThemeRepository; | ||
| import roomescape.time.Time; | ||
| import roomescape.time.TimeRepository; | ||
|
|
||
| @Component | ||
| public class DataInitializer implements CommandLineRunner { | ||
|
|
||
| private final MemberRepository memberRepository; | ||
| private final ThemeRepository themeRepository; | ||
| private final TimeRepository timeRepository; | ||
| private final ReservationRepository reservationRepository; | ||
|
|
||
| public DataInitializer( | ||
| MemberRepository memberRepository, | ||
| ThemeRepository themeRepository, | ||
| TimeRepository timeRepository, | ||
| ReservationRepository reservationRepository | ||
| ) { | ||
| this.memberRepository = memberRepository; | ||
| this.themeRepository = themeRepository; | ||
| this.timeRepository = timeRepository; | ||
| this.reservationRepository = reservationRepository; | ||
| } | ||
|
|
||
| @Override | ||
| @Transactional | ||
| public void run(String... args) throws Exception { | ||
| // 1. 관리자 계정 생성 | ||
| if (memberRepository.findByEmail("admin").isEmpty()) { | ||
| Member admin = new Member("admin", "admin", "admin", "ADMIN"); | ||
| memberRepository.save(admin); | ||
| System.out.println("관리자 계정이 생성되었습니다."); | ||
| } | ||
|
|
||
| // 2. 테마 데이터 생성 | ||
| if (themeRepository.count() == 0) { | ||
| Theme theme1 = new Theme("테마1", "테마1입니다."); | ||
| Theme theme2 = new Theme("테마2", "테마2입니다."); | ||
| Theme theme3 = new Theme("테마3", "테마3입니다."); | ||
|
|
||
| themeRepository.save(theme1); | ||
| themeRepository.save(theme2); | ||
| themeRepository.save(theme3); | ||
| System.out.println("테마 데이터가 생성되었습니다."); | ||
| } | ||
|
|
||
| // 3. 시간 데이터 생성 | ||
| if (timeRepository.count() == 0) { | ||
| Time time1 = new Time("10:00"); | ||
| Time time2 = new Time("12:00"); | ||
| Time time3 = new Time("14:00"); | ||
| Time time4 = new Time("16:00"); | ||
| Time time5 = new Time("18:00"); | ||
| Time time6 = new Time("20:00"); | ||
|
|
||
| timeRepository.save(time1); | ||
| timeRepository.save(time2); | ||
| timeRepository.save(time3); | ||
| timeRepository.save(time4); | ||
| timeRepository.save(time5); | ||
| timeRepository.save(time6); | ||
| System.out.println("시간 데이터가 생성되었습니다."); | ||
| } | ||
|
|
||
| if (reservationRepository.count() == 0) { | ||
| Member admin = memberRepository.findByEmail("admin") | ||
| .orElseThrow(() -> new RuntimeException("Admin not found")); | ||
|
|
||
| Time time1 = timeRepository.findById(1L).orElseThrow(); | ||
| Time time2 = timeRepository.findById(2L).orElseThrow(); | ||
| Time time3 = timeRepository.findById(3L).orElseThrow(); | ||
|
|
||
| Theme theme1 = themeRepository.findById(1L).orElseThrow(); | ||
| Theme theme2 = themeRepository.findById(2L).orElseThrow(); | ||
| Theme theme3 = themeRepository.findById(3L).orElseThrow(); | ||
|
|
||
| Reservation reservation1 = new Reservation("", "2024-03-01", time1, theme1, admin); | ||
| Reservation reservation2 = new Reservation("", "2024-03-01", time2, theme2, admin); | ||
| Reservation reservation3 = new Reservation("", "2024-03-01", time3, theme3, admin); | ||
|
|
||
| reservationRepository.save(reservation1); | ||
| reservationRepository.save(reservation2); | ||
| reservationRepository.save(reservation3); | ||
|
|
||
| Reservation reservation4 = new Reservation("브라운", "2024-03-01", time1, theme2); | ||
|
|
||
| reservationRepository.save(reservation4); | ||
| System.out.println("예약 데이터가 생성되었습니다."); | ||
| } | ||
|
|
||
| System.out.println("초기 데이터 로딩이 완료되었습니다."); | ||
| } | ||
| } |
48 changes: 48 additions & 0 deletions
48
src/main/java/roomescape/infrastructure/JwtTokenProvider.java
This file contains hidden or 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,48 @@ | ||
| package roomescape.infrastructure; | ||
|
|
||
| import io.jsonwebtoken.Claims; | ||
| import io.jsonwebtoken.Jws; | ||
| import io.jsonwebtoken.JwtException; | ||
| import io.jsonwebtoken.Jwts; | ||
| import io.jsonwebtoken.SignatureAlgorithm; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| import java.util.Date; | ||
|
|
||
| @Component | ||
| public class JwtTokenProvider { | ||
| @Value("${security.jwt.token.secret-key}") | ||
| private String secretKey; | ||
| @Value("${security.jwt.token.expire-length:3600000}") | ||
| private long validityInMilliseconds; | ||
|
|
||
| public String createToken(String payload) { | ||
| Claims claims = Jwts.claims().setSubject(payload); | ||
| Date now = new Date(); | ||
| Date validity = new Date(now.getTime() + validityInMilliseconds); | ||
|
|
||
| return Jwts.builder() | ||
| .setClaims(claims) | ||
| .setIssuedAt(now) | ||
| .setExpiration(validity) | ||
| .signWith(SignatureAlgorithm.HS256, secretKey) | ||
| .compact(); | ||
| } | ||
|
|
||
| public String getPayload(String token) { | ||
| return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); | ||
| } | ||
|
|
||
| public boolean validateToken(String token) { | ||
| try { | ||
| Jws<Claims> claims = Jwts.parser() | ||
| .setSigningKey(secretKey) | ||
| .parseClaimsJws(token); | ||
| return !claims.getBody().getExpiration().before(new Date()); | ||
| } catch (JwtException | IllegalArgumentException e) { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
|
|
This file contains hidden or 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 hidden or 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
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.
실행시켜서 몇개 api들 동작시켜보면 현재 로그가 매우매우매우 많이 뜨는 걸 확인할 수 있을텐데요
요 줄을 없애면 해결된답니다.
로그가 너무 많으면 확인하기 힘드니 적당히 보이는 것이 좋을 것 같아요!
Uh oh!
There was an error while loading. Please reload this page.
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.
저도 콘솔 창에 너무 많은 로그가 있어 해윤님이 말씀하신 방향으로 정리해보겠습니다!!!
위 코드를 반영해보니 컴파일에러가 발생하여 찾아보니
implementation 'org.springframework.boot:spring-boot-starter-data-jpa': SQL 대신 자바 객체(Entity)를 조작합니다. 인터페이스만 선언하면 Spring Data JPA가 실행 시점에 적절한 SQL을 자동으로 생성합니다.와 같다고 하여
리뷰어님이 말씀하신 방향으로 수정하기 위해
#logging.level.org.hibernate.SQL=DEBUG를 주석 처리해보았습니다!!
저도 덕분에 어떤 의존성이 어떤 역할을 하는지 확실히 알 수 있는 기회가 된 것 같습니다!
반영 커밋 :