Skip to content
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

Feat/11 : 무한스크롤 기능 구현 #12

Merged
merged 6 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ repositories {
}

dependencies {
// implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation group: 'org.webjars', name: 'stomp-websocket', version: '2.3.3-1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public enum ErrorStatus implements BaseErrorCode {
_UNAUTHORIZED(HttpStatus.UNAUTHORIZED,"COMMON401","인증이 필요합니다."),
_FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "금지된 요청입니다."),

// 멤버 관려 예외
//페이지 관련 에러
_PAGE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "PAGE2001", "page 번호는 0 이상이여야 합니다")
;
private final HttpStatus httpStatus;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ public enum SuccessStatus implements BaseCode {
_OK(HttpStatus.OK, "COMMON200","success"),

//멤버 관련 응답
MEMBER_ENTER(HttpStatus.OK, "MEMBER2001", "member entered")
MEMBER_ENTER(HttpStatus.OK, "MEMBER2001", "member entered"),

//방명록 관련 응답
MESSAGE_RETURN(HttpStatus.OK,"GUESTBOOK2001", "message list returned")
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,4 @@ public ApiResponse<MemberDto.MemberResponseDto> enter(){
return ApiResponse.of(SuccessStatus.MEMBER_ENTER, memberDto);
}



}
35 changes: 27 additions & 8 deletions src/main/java/Be9room/festime/controller/MessageController.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
package Be9room.festime.controller;

import Be9room.festime.dto.MessageDto;
import Be9room.festime.apiPayLoad.ApiResponse;
import Be9room.festime.apiPayLoad.code.status.SuccessStatus;
import Be9room.festime.converter.MessageConverter;
import Be9room.festime.domain.Message;
import Be9room.festime.dto.MessageChatDto;
import Be9room.festime.dto.MessageWebDto;
import Be9room.festime.enums.MessageType;
import Be9room.festime.service.MessageService;
import Be9room.festime.validation.annotation.CheckPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Slf4j
public class MessageController {
private final SimpMessagingTemplate template;
private final MessageService messageService;
/**
* 채팅 입장
* /pub/chat/enter 로 보내면 여기로 온다.
* @param message
*/
@MessageMapping(value = "/guestbook/enter")
public void enter(MessageDto message){
@Deprecated
public void enter(MessageChatDto message){
message.setMessageType(MessageType.ENTER.toString());
message.setMessage(message.getMemberName() + "님이 방명록에 참여했어요!");

/* 메세지 저장 부분 */
messageService.save(message);

template.convertAndSend("/topic/guestbook", message);
}
Expand All @@ -33,10 +45,10 @@ public void enter(MessageDto message){
* @param message
*/
@MessageMapping(value = "/guestbook/message")
public void message(MessageDto message){
public void message(MessageChatDto message){
message.setMessageType(MessageType.MESSAGE.toString());

/* 메세지 저장 부분 */
messageService.save(message);

template.convertAndSend("/topic/guestbook", message);
}
Expand All @@ -46,14 +58,21 @@ public void message(MessageDto message){
* @param message
*/
@MessageMapping(value = "/guestbook/leave")
public void leave(MessageDto message){
@Deprecated
public void leave(MessageChatDto message){
message.setMessageType(MessageType.LEAVE.toString());
message.setMessage(message.getMemberName() + "님이 방명록에서 나가셨어요!");

/* 메세지 저장 부분 */
messageService.save(message);

template.convertAndSend("/topic/guestbook", message);
}

@GetMapping(value = "/message")
public ApiResponse<MessageWebDto.MessageResponseDtoList> getMessageList(@CheckPage @RequestParam(name = "page") Integer page){
Page<Message> messagePage = messageService.getMessages(page);
MessageWebDto.MessageResponseDtoList messageResponseDtoList = MessageConverter.toMessageResponseDtoList(messagePage);
return ApiResponse.of(SuccessStatus.MESSAGE_RETURN, messageResponseDtoList);
}

}
}
34 changes: 34 additions & 0 deletions src/main/java/Be9room/festime/converter/MessageConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package Be9room.festime.converter;

import Be9room.festime.domain.Message;
import Be9room.festime.dto.MessageChatDto;
import Be9room.festime.dto.MessageWebDto;
import org.springframework.data.domain.Page;

import java.util.List;
import java.util.stream.Collectors;

public class MessageConverter {
public static MessageWebDto.MessageResponseDto toMessageResponseDto(Message message){
return MessageWebDto.MessageResponseDto.builder()
.memberName(message.getMemberName())
.memberId(message.getMemberId())
.message(message.getMessage())
.createdAt(message.getCreatedAt())
.build();
}
public static MessageWebDto.MessageResponseDtoList toMessageResponseDtoList(Page<Message> messagePage){
List<MessageWebDto.MessageResponseDto> messageList = messagePage.stream()
.map(MessageConverter::toMessageResponseDto)
.toList();

return MessageWebDto.MessageResponseDtoList.builder()
.messageDtoList(messageList)
.isLast(messagePage.isLast())
.isFirst(messagePage.isFirst())
.totalPage(messagePage.getTotalPages())
.totalElements(messagePage.getTotalElements())
.listSize(messageList.size())
.build();
}
}
24 changes: 24 additions & 0 deletions src/main/java/Be9room/festime/domain/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package Be9room.festime.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.time.LocalDateTime;

@Getter
@Document(collection = "messages")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Message {
@Id
private String id;
private String memberName;
private String memberId;
private String message;
private LocalDateTime createdAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class MessageDto {
public class MessageChatDto {
private String memberName;
private String memberId;
private String messageType;
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/Be9room/festime/dto/MessageWebDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package Be9room.festime.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

public class MessageWebDto {
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
public static class MessageResponseDtoList{
List<MessageResponseDto> messageDtoList;
Boolean isFirst;
Boolean isLast;
Long totalElements;
Integer listSize;
Integer totalPage;
}
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
public static class MessageResponseDto{
private String memberName;
private String memberId;
private String message;
private LocalDateTime createdAt;
}
}
12 changes: 12 additions & 0 deletions src/main/java/Be9room/festime/repository/MessageRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package Be9room.festime.repository;

import Be9room.festime.domain.Message;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.time.LocalDateTime;

public interface MessageRepository extends MongoRepository<Message, String> {
Page<Message> findMessagesByCreatedAtAfterOrderByCreatedAtDesc(LocalDateTime time, PageRequest pageRequest);
}
10 changes: 10 additions & 0 deletions src/main/java/Be9room/festime/service/MessageService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package Be9room.festime.service;

import Be9room.festime.domain.Message;
import Be9room.festime.dto.MessageChatDto;
import org.springframework.data.domain.Page;

public interface MessageService {
Message save(MessageChatDto messageChatDto);
Page<Message> getMessages(Integer page);
}
34 changes: 34 additions & 0 deletions src/main/java/Be9room/festime/service/MessageServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package Be9room.festime.service;

import Be9room.festime.domain.Message;
import Be9room.festime.dto.MessageChatDto;
import Be9room.festime.repository.MessageRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class MessageServiceImpl implements MessageService {
private final MessageRepository messageRepository;

@Override
public Message save(MessageChatDto messageChatDto) {
Message message = Message.builder()
.memberId(messageChatDto.getMemberId())
.memberName(messageChatDto.getMemberName())
.message(messageChatDto.getMessage())
.createdAt(LocalDateTime.now())
.build();

return messageRepository.save(message);
}

@Override
public Page<Message> getMessages(Integer page) {
return messageRepository.findMessagesByCreatedAtAfterOrderByCreatedAtDesc(LocalDateTime.now().minusHours(3),PageRequest.of(page, 30));
}
}
17 changes: 17 additions & 0 deletions src/main/java/Be9room/festime/validation/annotation/CheckPage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package Be9room.festime.validation.annotation;

import Be9room.festime.validation.validator.CheckPageValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = CheckPageValidator.class)
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPage {
String message() default "페이지는 0 이상이여야 합니다.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package Be9room.festime.validation.validator;

import Be9room.festime.apiPayLoad.code.status.ErrorStatus;
import Be9room.festime.validation.annotation.CheckPage;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class CheckPageValidator implements ConstraintValidator<CheckPage, Integer>{
@Override
public void initialize(CheckPage constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}

@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
boolean isValid = true;
if(value < 0){
isValid = false;
}
if(!isValid){
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(ErrorStatus._PAGE_ERROR.toString()).addConstraintViolation();
}
return isValid;
}
}
4 changes: 3 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
spring:
application:
name: festime_BE

data:
mongodb:
uri: ${MONGO_HOST}

rabbit:
host: ${RABBIT_HOST}
Loading