https://github.com/lazygyu97/seoulmate/pull/53
회원 탈퇴 신청 시 바로 회원 탈퇴(해당 user의 정보 삭제)가 되는 것이 아닌 회원 탈퇴 신청을 한 user를 withdrawalRepository에 담아주고 withdrawals table에서 확인할 수 있게 만들었습니다.
회원 탈퇴의 유예 기간은 7일이며 public void cleanupExpiredWithdrawals()의 LocalDateTime standardTime = LocalDateTime.now().minusDays(7); 에서 설정해주었습니다.
withdrawals table의 expire_time에서 삭제가 완료될 날짜와 시간을 보여주는데 이 부분은 UserService의 public ResponseEntity withdrawUser(User user)에서 LocalDateTime expireTime = LocalDateTime.now().plusDays(7); 부분입니다.
LocalDateTime standardTime = LocalDateTime.now().minusDays(7); 와 LocalDateTime expireTime = LocalDateTime.now().plusDays(7);의 날짜, 시간을 갖게 해주어야 withdrawals table의 expire_time에서 알맞은 회원 탈퇴 시간 확인이 가능합니다.
회원이 탈퇴 신청을 하고 갖는 유예 기간은 7일로 설정했습니다.
그 7일 안에 회원이 DENY 역할을 갖고 어떤 행동을 할 수 있는지에 대한 설정과 회원 탈퇴 신청을 취소하는 기능은 JwtAuthenticationFilter와 관련 있어서 팀장님이 확인해주신다고 하셨습니다.
public class WithdrawalScheduler에서 @scheduled(cron = "0 30 7,15,23 * * *")를 이용하여 스케줄러가 매일 7시 30분/15시 30분/23시 30분에 작동하게 설정하고 회원 탈퇴 유예 기간이 만료된 정보들을 검사하고 탈퇴 처리를 합니다.
ex) 10일 13시에 탈퇴한 회원 A -> 17일 15시 30분에 작동하는 스케줄러가 회원 탈퇴 처리
ex) 11일 15시 32분에 탈퇴한 회원 B -> 18일 23시 30분에 작동하는 스케줄러가 회원 탈퇴 처리
ex) 11일 23시 57분에 탈퇴한 회원 C -> 19일 7시 30분에 작동하는 스케줄러가 회원 탈퇴 처리
탈퇴 유예 기간은 7일이며, 2023-09-07 19:33에 탈퇴 신청을 한 user_id 17번의 user의 정보가 withdrawals table에서 확인됩니다.
expire_time에 보이는 것과 같이 2023-09-14 19:33에 탈퇴 완료 예정이며 23시 30분에 작동하는 스케줄러로 인해 회원 탈퇴(회원 정보 삭제)가 이루어집니다. 예정된 탈퇴 시간과 차이가 있으며 약 5~6시간이 더 걸릴 것으로 예상됩니다.
만료 기간이 다 된 정보를 스케줄러가 감지하여 withdrawals table에서 해당 데이터를 삭제하고 삭제된 데이터의 같은 user_id를 갖고 있는 회원 정보(컬럼)를 users table에서 삭제해서 회원 탈퇴가 이루어지게 됩니다.
오류…
java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.sparta.seoulmate.entity.redishash.Withdrawal]
com.sparta.seoulmate.entity.redishash.Withdrawal 클래스가 직렬화 가능한(Serializable) 형태로 구현되어 있지 않아서 발생Withdrawal 클래스는 이러한 직렬화를 지원하지 않고 있다!Serializable 인터페이스를 구현import java.io.Serializable;public class Withdrawal implements SerializableError starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-09-05T20:15:56.183+09:00 ERROR 18676 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 11 of constructor in com.sparta.seoulmate.service.UserService required a bean of type 'org.springframework.data.redis.core.RedisTemplate' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.data.redis.core.RedisTemplate' in your configuration.
Process finished with exit code 1private final RedisTemplate<String, String> redisTemplate;private final RedisTemplate<String, String> redisTemplate; ```java
private final UserService userService;
```
```java
private final RedisMessagePublisher redisMessagePublisher;
```
Withdrawal withdrawal = Withdrawal.builder()
.id(targetUser.getId())
.requestTime(now)
.scheduledDeletionTime(scheduledDeletionTime)
.status(WithdrawalStatusEnum.PENDING) // 탈퇴 상태를 대기 중으로 설정
.build();LocalDateTime now = LocalDateTime.now();
LocalDateTime scheduledDeletionTime = now.plusMinutes(1);
Withdrawal withdrawal = Withdrawal.builder()
.user(targetUser) // 사용자 엔티티를 설정
.requestTime(now)
.scheduledDeletionTime(scheduledDeletionTime)
.status(WithdrawalStatusEnum.PENDING)
.build();참고
gradle에 websocket 임포트
import lombok.Data; 즉, @Data 어노테이션을 쓰면 @Getter 역할이 채워진다?!
ec2가 뭥미? → 아마존웹서비스(WAS)에서 제공해주는 서비스(서버)
크롬 확장 프로그램인 talend api tster와 socket test client 를 사용해서 채팅 방만들기

@Override 어노테이션은 자바에서 메소드를 오버라이드(재정의)할 때 사용하는 어노테이션입니다. @Override 어노테이션을 사용하여 해당 메소드가 슈퍼클래스나 인터페이스에서 상속된 메소드를 오버라이드하고 있음을 명시적으로 나타냅니다. 그러나 위의 코드에서는 클래스 정의에 @Override 어노테이션을 사용하고 있지 않습니다. 따라서 @Override 어노테이션을 삭제해도 상관 없습니다. 이 어노테이션은 필수적으로 사용할 필요는 없으며, 클래스가 인터페이스의 메소드를 구현하거나 슈퍼클래스의 메소드를 오버라이드할 때만 사용됩니다. 현재 코드에서는 인터페이스를 구현하는 것이 아니며, @Override 어노테이션을 사용하지 않아도 됩니다. 따라서 @Override 어노테이션을 삭제해도 코드에는 영향을 주지 않습니다. 코드의 가독성을 높이기 위해 어노테이션을 사용하는 것이 좋을 수 있지만, 삭제하더라도 기능적인 측면에서는 문제가 없습니다.파라미터 안에서 Ctrl+P 하면 파라미터 안에 뭐가 들어가는지 종류를 볼 수 있다
@RequestParam에는 대문자가 들어갈 수 없다
uuid는 랜덤으로 생기는 String이기 때문에 상관없다
대문자를 권장하지 않는 이유?
- 약속…
public ChatRoomDto createRoom(@RequestParam(name = "room-name") String roomName, @AuthenticationPrincipal UserDetailsImpl userDetails) {
return chatService.createRoom(roomName, userDetails.getUser());
}
(@RequestParam(name = "room-name")을 해주면 api에서 room-name로 표시될 수 있다
String roomName은 해당 값을 넣어주는 것이고
api 입력은 (@RequestParam(name = "room-name")의 room-name로 적어주어 사용한다
RoomId를 가지고 WebSocketTesting(WebSocketClient)으로 test…!
튜터님 추천
WebSocketTesting 참고
지금까지 참고 했던 블로그에서 썼던 WebSocketTest 확장 프로그램은 Web Socket Client이 아닌 Simple WebSocket Client였다!!!!!!!!
Web Socket Client 
Simple WebSocket Client 
연결이 안되는 문제
ChatService의 no usages 정리
public List<ChatRoomDto> findRooms() {
return new ArrayList<>(chatRooms.values());
}
public ChatRoomDto selectRoomById(String roomId) {
ChatRoom room = chatRoomRepository.findByUuid(roomId)
.orElseThrow(() -> new IllegalArgumentException("해당 채팅방이 존재하지 않습니다."));
return ChatRoomDto.builder()
.roomId(room.getUuid())
.roomName(room.getRoomName())
.build();
}
ChatController 변경
// 채팅방 생성
@PostMapping("/chats")
public ChatRoomDto createChatRoom(@RequestParam(name = "room-name") String roomName, @AuthenticationPrincipal UserDetailsImpl userDetails) {
return chatService.createChatRoom(roomName, userDetails.getUser());
}// 채팅방 생성
@PostMapping("/chats")
public ResponseEntity<ChatRoomDto> createChatRoom(@RequestParam(name = "room-name") String roomName, @AuthenticationPrincipal UserDetailsImpl userDetails) {
ChatRoomDto chatRoomDto = chatService.createChatRoom(roomName, userDetails.getUser());
return ResponseEntity.ok().body(chatRoomDto);
}Simple WebSocket Client 으로 테스트Simple WebSocket Client Server Location - URL : ws://localhost:8080/ws/chat@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "ws/chat").setAllowedOrigins("*");
}Simple WebSocket Client Request{
"type":"ENTER",
"roomId":"7641f39a-8b7e-4ffd-9360-a4214a904778",
"sender":"user1",
"message":"test-talk"
}→ 코드 리팩토링 문제인지 내가 모르거나 빠뜨린 무엇이 있는 건지 OPENED까지는 되지만 Message Log에서 수행되지 않음