코트카타
39) 최대공약수와 최소공배수
나의 풀이
class Solution {
public int solution(int n) {
int answer = 0;
StringBuilder sb = new StringBuilder();
while(n>0){
sb.append(n%3);
n/=3;
}
String reversed = new StringBuilder(sb).reverse().toString();
int three = 1;
for (int i = 0; i < reversed.length(); i++) {
answer += Character.getNumericValue(reversed.charAt(i)) * three;
three*=3;
}
return answer;
}
}
StringBuilder를 사용해보았다.
앞으로도 자주 사용하고 싶다.
다른 분들의 풀이
class Solution {
public int solution(int n) {
String a = "";
while(n > 0){
a = (n % 3) + a;
n /= 3;
}
a = new StringBuilder(a).reverse().toString();
return Integer.parseInt(a,3);
}
}
출처:https://school.programmers.co.kr/learn/courses/30/lessons/68935/solution_groups?language=java
3진법으로 바꾸어주는 게 너무 신기하다...
2025.02.07(금)
필수
Lv 2. 유저 CRUD
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "com.example.scheduledevelop.domain.entity.Member.getName()" because the return value of "com.example.scheduledevelop.domain.entity.Schedule.getMember()" is null] with root cause
생성자 주입이나 Setter 주입을 통해 Member 값을 넣어줘야 하는데 그렇게 하지 않아서 발생했다.
public Schedule(String title, String contents, Member member) {
this.title = title;
this.contents = contents;
this.member = member;
}
따라서 위와 같이 Schedule 클래스의 생성자에 member도 포함시키고
Member findMember = memberRepository.findMemberByEmailOrElseThrow(memberEmail);
Schedule schedule = new Schedule(title, contents, member);
Service에서 email로 해당 Member를 찾아온 후,
생성자에 member 값을 세팅해주었다.
필수
Lv 4. 로그인(인증)
일정 생성, 수정, 삭제시 로그인 Session 값을 가져오는 방법
로그인 기능 자체는 구현을 완료했다.
하지만 로그인 후, 일정을 생성, 수정, 삭제할 때 해당 세션 값을 가져오는 방법에 대해 고민이 생겼다.
그래서 숙련 Spring 2주차 강의에서 Session 부분을 다시 들으며 복습했다.
그리고 강의에서 해답을 찾을 수 있었다.
Spring에서는 Session을 쉽게 다루도록 @SessionAttribute라는 어노테이션이 제공된다고 한다.
사실 다른 방법도 있지만 더 깔끔해 보여서 나는 이 어노테이션을 사용하기로 햇다.
@SessionAttribute
- request.getSession(true); 와는 다르게 Session을 새로 생성하는 기능은 없다.
- 이미 로그인이 완료된 사용자를 찾는 경우 즉, Session이 있는 경우에 사용한다.
이미 AuthController에서 Session을 생성하기 때문에 생성 기능은 필요하지 않았다.
일정 Controller에서는 로그인 후, 즉 Session이 있는 경우에 사용하면 되는 것이었다.
@PostMapping
public ResponseEntity<ScheduleResponseDto> save(
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember,
@RequestBody ScheduleSaveRequestDto requestDto) {
// 생성 로직
ScheduleResponseDto scheduleResponseDto
= scheduleService.save(requestDto.getTitle(), requestDto.getContents(),loginMember);
return new ResponseEntity<>(scheduleResponseDto, HttpStatus.CREATED);
}
따라서 Controller에서 해당 Session을 매개변수로 받아서 Member타입의 변수에 저장했다.
그리고 Service에 같이 매개변수로 넣었다.
@Transactional
public ScheduleResponseDto save(String title, String contents, Member member) {
Schedule schedule = new Schedule(title, contents, member);
Schedule savedSchedule = scheduleRepository.save(schedule);
return new ScheduleResponseDto(
savedSchedule.getId(),
savedSchedule.getTitle(),
savedSchedule.getContents(),
savedSchedule.getMember().getName(),
savedSchedule.getMember().getEmail()
);
}
이를 Service에서 Schedule 생성자를 통해 loginMember 값을 주입할 수 있었다.
작성자만 일정을 수정, 삭제하게 하는 방법
위에서 매개변수로 받아온 loginMember 변수를 활용하기로 했다.
각각의 id가 동일한지 비교하는 로직을 만들고
같지 않다면 예외처리를 하고,
같다면 수정, 삭제 로직을 수행하도록 할 계획이었다.
그러나 위와 같은 생각으로 구현을 하고 Postman을 통해 테스트를 하는데
이상한 점을 발견하게 되었다.
분명 작성자인데 수정, 삭제가 작동하지 않는 것이었다.
System.out.println("findMemberId = " + findMemberId);
위와 같이 print를 통해 각각의 id를 조회하고 나니 원인을 찾을 수 있었다...
memberId와 scheduleId를 비교하고 있으니 둘이 다를 수 밖에...
따라서 아래와 같이 findMember라는 새로운 Service 메서드를 만들어서
scheduleId에 해당하는 Member를 찾고 그 Member의 아이디를 찾아서 이를 비교했다.
@PatchMapping("/{scheduleId}")
public ResponseEntity<Void> updateTitleAndContents(
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember,
@PathVariable("scheduleId") Long id,
@RequestBody UpdateTitleAndContentsRequestDto requestDto
) {
Member findMember = scheduleService.findMember(id);
Long findMemberId = findMember.getId();
// 작성자만 수정 가능
if (!loginMember.getId().equals(findMemberId)){
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
// 수정 로직
scheduleService.updateTitleContents(id, requestDto.getTitle(), requestDto.getContents());
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping("/{scheduleId}")
public ResponseEntity<Void> delete(
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember,
@PathVariable("scheduleId") Long id
){
Member findMember = scheduleService.findMember(id);
Long findMemberId = findMember.getId();
// 작성자만 삭제 가능
if (!loginMember.getId().equals(findMemberId)){
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
// 삭제 로직
scheduleService.delete(id);
return new ResponseEntity<>(HttpStatus.OK);
}
오늘은 계획대로 필수 과제 구현을 모두 끝내게 되어서 뿌듯하다.
다음 주에는 도전과제를 도전할 계획이다.
다음 주도 화이팅이다!
'CODING > 스파르타 내일배움캠프 TIL' 카테고리의 다른 글
37_최대공약수와 최소공배수_일정관리 개인과제 피드백_일정관리 Develop 개인과제 Lv 1, 2 구현중_25.2.6(목) (0) | 2025.02.06 |
---|---|
일정 관리 앱 Develop 개인과제 관련 트러블슈팅 TIL 모음 (0) | 2025.02.06 |
36_직사각형 별찍기_스탠다드 트랜잭션, 인덱스_숙련 Spring 3주차_25.2.5(수) (0) | 2025.02.05 |
35_행렬의 덧셈_일정관리 개인과제 해설_숙련 Spring 1,2주차_25.2.4(화) (1) | 2025.02.04 |
34_문자열 다루기 기본_스탠다드 데이터베이스 연관관계 매핑_일정관리 과제 Lv 5 구현완료_25.2.3(월) (0) | 2025.02.03 |