diff --git a/src/main/java/com/gdsc/petwalk/auth/jwt/filter/JwtExceptionHandlerFilter.java b/src/main/java/com/gdsc/petwalk/auth/jwt/filter/JwtExceptionHandlerFilter.java index b2fa421..9015d7e 100644 --- a/src/main/java/com/gdsc/petwalk/auth/jwt/filter/JwtExceptionHandlerFilter.java +++ b/src/main/java/com/gdsc/petwalk/auth/jwt/filter/JwtExceptionHandlerFilter.java @@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -27,19 +28,23 @@ public class JwtExceptionHandlerFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { try { filterChain.doFilter(request, response); - } catch (NotValidTokenException e){ - HttpStatus httpStatus = e.getErrorCode().getHttpStatus(); - String message = e.getErrorCode().getMessage(); + } catch (NotValidTokenException e) { + handleException(response, e.getErrorCode().getHttpStatus(), e.getErrorCode().getMessage()); + } catch (UsernameNotFoundException e) { + handleException(response, HttpStatus.UNAUTHORIZED, e.getMessage()); + } + } - Map jsonResponse = new HashMap<>(); - jsonResponse.put("status", httpStatus.value()); - jsonResponse.put("message", message); + private void handleException(HttpServletResponse response, HttpStatus status, String message) throws IOException { + Map jsonResponse = new HashMap<>(); + jsonResponse.put("status", false); + jsonResponse.put("message", message); + jsonResponse.put("errorCode", status.value()); - response.setStatus(httpStatus.value()); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); + response.setStatus(status.value()); + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); - objectMapper.writeValue(response.getWriter(), jsonResponse); - } + objectMapper.writeValue(response.getWriter(), jsonResponse); } } diff --git a/src/main/java/com/gdsc/petwalk/domain/member/entity/Member.java b/src/main/java/com/gdsc/petwalk/domain/member/entity/Member.java index b2e4921..9292ec6 100644 --- a/src/main/java/com/gdsc/petwalk/domain/member/entity/Member.java +++ b/src/main/java/com/gdsc/petwalk/domain/member/entity/Member.java @@ -80,7 +80,7 @@ public class Member { @OneToMany(mappedBy = "commenter") private List comments = new ArrayList<>(); - @OneToMany(mappedBy = "writer") + @OneToMany(mappedBy = "member") private List walkInvitations = new ArrayList<>(); @Builder diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/controller/HomeController.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/controller/HomeController.java index 9ea37a9..a1277c1 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/controller/HomeController.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/controller/HomeController.java @@ -1,14 +1,12 @@ package com.gdsc.petwalk.domain.walkinvitation.controller; -import com.gdsc.petwalk.auth.itself.dto.request.SignUpRequestDto; -import com.gdsc.petwalk.domain.walkinvitation.dto.request.WalkInvitaionCreateRequestDto; +import com.gdsc.petwalk.domain.walkinvitation.dto.request.WalkInvitationCreateRequestDto; import com.gdsc.petwalk.domain.walkinvitation.dto.response.HomePageResponseDto; import com.gdsc.petwalk.domain.walkinvitation.dto.response.WalkInvitationDetailsResponseDto; +import com.gdsc.petwalk.domain.walkinvitation.dto.response.WalkInvitationResultDto; import com.gdsc.petwalk.domain.walkinvitation.service.WalkInvitationService; import com.gdsc.petwalk.global.principal.PrincipalDetails; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -38,37 +36,53 @@ public class HomeController { @PreAuthorize("isAuthenticated()") @Operation(summary = "홈 화면 글쓰기 로직", description = "홈 화면 글쓰기 로직, WalkInvitaionCreateRequestDto는 application/json형식, uploadPhotos는 multipart/form-data로 한번에 form-data 형식으로 보내주면 됨.
try it out을 누르면 dto 정보를 확인 할 수 있습니다. swagger에서 직접 테스트는 안되니 참고하세요!") @ApiResponse(responseCode = "200", description = "글쓰기 성공 시 Long 타입 id 값 반환") - public ResponseEntity createWalkInvitation( - @RequestPart("walkInvitaionCreateRequestDto") WalkInvitaionCreateRequestDto request, + public ResponseEntity> createWalkInvitation( + @RequestPart("walkInvitationCreateRequestDto") WalkInvitationCreateRequestDto request, @RequestPart("uploadPhotos") MultipartFile[] multipartFiles, - @AuthenticationPrincipal PrincipalDetails principalDetails){ + @AuthenticationPrincipal PrincipalDetails principalDetails) { Long savedId = walkInvitationService.createWalkInvitation(request, multipartFiles, principalDetails); - return ResponseEntity.ok().body(savedId); + return ResponseEntity.ok().body(WalkInvitationResultDto.builder() + .status(true) + .code(200) + .message("글 등록 성공!") + .data(savedId) + .build()); } @GetMapping("/{walkInvitationId}") @Operation(summary = "홈 화면 글 하나 조회 로직", description = "홈 화면 글 하나 조회하는 로직") @ApiResponse(responseCode = "200", description = "글쓰기 성공 시 WalkInvitationDetailsResponseDto 타입 dto 반환") - public ResponseEntity getDetail( + public ResponseEntity> getDetail( @PathVariable("walkInvitationId") Long id - ){ + ) { WalkInvitationDetailsResponseDto response = walkInvitationService.getHomeDetailsById(id); - return ResponseEntity.ok().body(response); + return ResponseEntity.ok().body(WalkInvitationResultDto.builder() + .status(true) + .code(200) + .message("홈 화면 글 상세내용 불러오기 성공!") + .data(response) + .build()); } @GetMapping("/me") @PreAuthorize("isAuthenticated()") - @Operation(summary = "홈 화면에 보여질 글들 조회 로직", description = "홈 화면 글들 조회하는 로직이고, 기본은 오늘 하루치만") - @ApiResponse(responseCode = "200", description = "글쓰기 성공 시 HomePageResponseDto 타입 dto 반환") - public ResponseEntity> getHomepageLists( + @Operation(summary = "홈 화면에 보여질 글들 조회 로직", description = "홈 화면 글들 조회하는 로직이고, 기본은 오늘 하루치만... 추후 글 불러오기 api 필요") + @ApiResponse(responseCode = "200", description = "글쓰기 성공 시 HomePageResponseDto 타입의 list 반환") + public ResponseEntity>> getHomepageLists( @AuthenticationPrincipal PrincipalDetails principalDetails - ){ + ) { List homepageLists = walkInvitationService.getTodayHomePageLists(principalDetails); - return ResponseEntity.ok().body(homepageLists); + return ResponseEntity.ok().body(WalkInvitationResultDto.>builder() + .status(true) + .code(200) + .message("홈 화면 글 불러오기 성공!") + .data(homepageLists) + .build() + ); } } diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/request/WalkInvitaionCreateRequestDto.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/request/WalkInvitationCreateRequestDto.java similarity index 80% rename from src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/request/WalkInvitaionCreateRequestDto.java rename to src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/request/WalkInvitationCreateRequestDto.java index b3e37c0..360548c 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/request/WalkInvitaionCreateRequestDto.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/request/WalkInvitationCreateRequestDto.java @@ -2,12 +2,10 @@ import lombok.Data; -import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; @Data -public class WalkInvitaionCreateRequestDto { +public class WalkInvitationCreateRequestDto { private String title; private String content; diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/HomePageResponseDto.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/HomePageResponseDto.java index c5c5de6..cc4b2e7 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/HomePageResponseDto.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/HomePageResponseDto.java @@ -1,25 +1,24 @@ package com.gdsc.petwalk.domain.walkinvitation.dto.response; -import com.gdsc.petwalk.domain.walkinvitation.entity.WalkInvitation; +import com.gdsc.petwalk.domain.walkinvitation.entity.WalkingStatus; import lombok.Builder; import lombok.Data; -import java.time.LocalDateTime; -import java.util.List; - @Data public class HomePageResponseDto { + private Long id; // 글 id private String title; private double latitude; // 산책 위치 위도 private double longitude; // 산책 위치 경도 private String detailedLocation; // 세부 위치 - private LocalDateTime walkDateTime; - private String walkingStatus; // 산책 상태 - + private String walkDateTime; + private WalkingStatus walkingStatus; // 산책 상태 private String walkInvitationPhotoUrl; // 썸네일 + private String timeDifference; // 몇분 전 올라온 글인지 @Builder - public HomePageResponseDto(String title, double latitude, double longitude, String detailedLocation, LocalDateTime walkDateTime, String walkingStatus, String walkInvitationPhotoUrl) { + public HomePageResponseDto(Long id, String title, double latitude, double longitude, String detailedLocation, String walkDateTime, WalkingStatus walkingStatus, String walkInvitationPhotoUrl, String timeDifference) { + this.id = id; this.title = title; this.latitude = latitude; this.longitude = longitude; @@ -27,22 +26,6 @@ public HomePageResponseDto(String title, double latitude, double longitude, Stri this.walkDateTime = walkDateTime; this.walkingStatus = walkingStatus; this.walkInvitationPhotoUrl = walkInvitationPhotoUrl; - } - - - public static List getListFrom(List walkInvitations) { - - return walkInvitations.stream().map(walkInvitation -> { - return HomePageResponseDto.builder() - .title(walkInvitation.getTitle()) - .latitude(walkInvitation.getLatitude()) - .longitude(walkInvitation.getLongitude()) - .detailedLocation(walkInvitation.getDetailedLocation()) - .walkDateTime(walkInvitation.getWalkStartDateTime()) - .walkingStatus(walkInvitation.getWalkingStatus()) - // .walkInvitationPhotoUrl(walkInvitation.getPhotoUrls().get(0).getPhotoUrl()) - .walkInvitationPhotoUrl(null) - .build(); - }).toList(); + this.timeDifference = timeDifference; } } diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationDetailsResponseDto.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationDetailsResponseDto.java index 5064506..1fdec68 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationDetailsResponseDto.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationDetailsResponseDto.java @@ -3,7 +3,6 @@ import lombok.Builder; import lombok.Data; -import java.time.LocalDateTime; import java.util.List; @Data @@ -14,15 +13,17 @@ public class WalkInvitationDetailsResponseDto { private double latitude; // 산책 위치 위도 private double longitude; // 산책 위치 경도 private String detailedLocation; // 세부 위치 - private LocalDateTime walkDateTime; // 산책 날짜 + private String walkDateTime; // 산책 날짜 private String walkingStatus; - private List WalkInvitationPhotoUrls; + private List walkInvitationPhotoUrls; + + private Long memberId; private String memberPhotoUrl; private String memberName; @Builder - public WalkInvitationDetailsResponseDto(String title, String content, double latitude, double longitude, String detailedLocation, LocalDateTime walkDateTime, String walkingStatus, List walkInvitationPhotoUrls, String memberPhotoUrl, String memberName) { + public WalkInvitationDetailsResponseDto(String title, String content, double latitude, double longitude, String detailedLocation, String walkDateTime, String walkingStatus, List walkInvitationPhotoUrls, Long memberId, String memberPhotoUrl, String memberName) { this.title = title; this.content = content; this.latitude = latitude; @@ -30,7 +31,8 @@ public WalkInvitationDetailsResponseDto(String title, String content, double lat this.detailedLocation = detailedLocation; this.walkDateTime = walkDateTime; this.walkingStatus = walkingStatus; - WalkInvitationPhotoUrls = walkInvitationPhotoUrls; + this.walkInvitationPhotoUrls = walkInvitationPhotoUrls; + this.memberId = memberId; this.memberPhotoUrl = memberPhotoUrl; this.memberName = memberName; } diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationResultDto.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationResultDto.java new file mode 100644 index 0000000..b8763d1 --- /dev/null +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/dto/response/WalkInvitationResultDto.java @@ -0,0 +1,15 @@ +package com.gdsc.petwalk.domain.walkinvitation.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class WalkInvitationResultDto { + private Boolean status; + private int code; + private String message; + private T data; +} diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkInvitation.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkInvitation.java index 9e9f0e6..07c99cf 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkInvitation.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkInvitation.java @@ -41,18 +41,19 @@ public class WalkInvitation { @Column(nullable = false) private LocalDateTime walkStartDateTime; // 산책 날짜 - private String walkingStatus; // 산책 상태 + @Enumerated(EnumType.STRING) + private WalkingStatus walkingStatus; // 산책 상태 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") - private Member writer; // 게시글 작성자 + private Member member; // 게시글 작성자 @Setter @OneToMany(mappedBy = "walkInvitation", cascade = CascadeType.ALL, orphanRemoval = true) private List photoUrls = new ArrayList<>(); @Builder - public WalkInvitation(Long id, String title, String content, double latitude, double longitude, String detailedLocation, LocalDateTime walkStartDateTime, String walkingStatus, Member writer, List photoUrls) { + public WalkInvitation(Long id, String title, String content, double latitude, double longitude, String detailedLocation, LocalDateTime walkStartDateTime, WalkingStatus walkingStatus, Member member, List photoUrls) { this.id = id; this.title = title; this.content = content; @@ -61,7 +62,7 @@ public WalkInvitation(Long id, String title, String content, double latitude, do this.detailedLocation = detailedLocation; this.walkStartDateTime = walkStartDateTime; this.walkingStatus = walkingStatus; - this.writer = writer; + this.member = member; this.photoUrls = photoUrls; } diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkingStatus.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkingStatus.java new file mode 100644 index 0000000..c3859da --- /dev/null +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/entity/WalkingStatus.java @@ -0,0 +1,5 @@ +package com.gdsc.petwalk.domain.walkinvitation.entity; + +public enum WalkingStatus { + BEFORE_WALK, DURING_WALK, AFTER_WALK +} diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/repository/WalkInvitationRepository.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/repository/WalkInvitationRepository.java index 5190c93..3f49496 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/repository/WalkInvitationRepository.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/repository/WalkInvitationRepository.java @@ -11,7 +11,7 @@ import java.util.List; public interface WalkInvitationRepository extends JpaRepository { - List findAllByWriter(Member member); + List findAllByMember(Member member); List findAllByWalkStartDateTimeBetween(LocalDateTime start, LocalDateTime end); diff --git a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/service/WalkInvitationService.java b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/service/WalkInvitationService.java index 94aab67..ead439e 100644 --- a/src/main/java/com/gdsc/petwalk/domain/walkinvitation/service/WalkInvitationService.java +++ b/src/main/java/com/gdsc/petwalk/domain/walkinvitation/service/WalkInvitationService.java @@ -4,10 +4,11 @@ import com.gdsc.petwalk.domain.member.repository.MemberRepository; import com.gdsc.petwalk.domain.photo.entity.Photo; import com.gdsc.petwalk.domain.photo.service.PhotoService; -import com.gdsc.petwalk.domain.walkinvitation.dto.request.WalkInvitaionCreateRequestDto; +import com.gdsc.petwalk.domain.walkinvitation.dto.request.WalkInvitationCreateRequestDto; import com.gdsc.petwalk.domain.walkinvitation.dto.response.HomePageResponseDto; import com.gdsc.petwalk.domain.walkinvitation.dto.response.WalkInvitationDetailsResponseDto; import com.gdsc.petwalk.domain.walkinvitation.entity.WalkInvitation; +import com.gdsc.petwalk.domain.walkinvitation.entity.WalkingStatus; import com.gdsc.petwalk.domain.walkinvitation.repository.WalkInvitationRepository; import com.gdsc.petwalk.global.principal.PrincipalDetails; import lombok.RequiredArgsConstructor; @@ -16,8 +17,12 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.time.Duration; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; import java.util.List; +import java.util.Locale; import java.util.NoSuchElementException; @Service @@ -29,45 +34,37 @@ public class WalkInvitationService { private final WalkInvitationRepository walkInvitationRepository; private final PhotoService photoService; + /** + * + * 핵심 비지니스 로직 모음 + */ public WalkInvitationDetailsResponseDto getHomeDetailsById(Long id) { - //예외 처리 이후 수정 WalkInvitation walkInvitation = walkInvitationRepository.findById(id) - .orElseThrow(() -> new NoSuchElementException("WalkInvitaion이 없습니다")); + .orElseThrow(() -> new NoSuchElementException("해당 id에 해당하는 글이 없습니다")); - Member member = walkInvitation.getWriter(); + Member member = walkInvitation.getMember(); List photoUrls = walkInvitation.getPhotoUrls().stream() .map(Photo::getPhotoUrl) .toList(); - return WalkInvitationDetailsResponseDto.builder() - .title(walkInvitation.getTitle()) - .content(walkInvitation.getContent()) - .latitude(walkInvitation.getLatitude()) - .longitude(walkInvitation.getLongitude()) - .detailedLocation(walkInvitation.getDetailedLocation()) - .walkDateTime(walkInvitation.getWalkStartDateTime()) - .walkingStatus(walkInvitation.getWalkingStatus()) - .walkInvitationPhotoUrls(photoUrls) - .memberName(member.getNickName()) - .memberPhotoUrl(member.getPhotoUrl()) - .build(); + return getWalkInvitationDetailsResponseDto(walkInvitation, photoUrls, member); } - public Long createWalkInvitation(WalkInvitaionCreateRequestDto request, - MultipartFile[] multipartFiles, PrincipalDetails principalDetails) { - + public Long createWalkInvitation(WalkInvitationCreateRequestDto request, + MultipartFile[] multipartFiles, PrincipalDetails principalDetails) { + // JPA 영속화 Member member = memberRepository.findByEmail(principalDetails.getMember().getEmail()) .orElseThrow(() -> new UsernameNotFoundException("해당 Email에 해당하는 유저가 없습니다")); WalkInvitation walkInvitation = WalkInvitation.builder() - .writer(member) + .member(member) .title(request.getTitle()) .content(request.getContent()) .latitude(request.getLatitude()) .longitude(request.getLongitude()) .detailedLocation(request.getDetailedLocation()) .walkStartDateTime(request.getWalkStartDateTime()) - .walkingStatus("산책 대기 중") + .walkingStatus(WalkingStatus.BEFORE_WALK) .build(); member.getWalkInvitations().add(walkInvitation); @@ -83,13 +80,85 @@ public Long createWalkInvitation(WalkInvitaionCreateRequestDto request, public List getTodayHomePageLists(PrincipalDetails principalDetails) { // principalDetails를 가져온 이유는, 자기 주위에 산책글을 보여주기 위함. 이후 로직추가 - // 기본은 지금부터 내일 이 시간까지 walkInvitation만 가져오기 + // 기본은 지금부터 내일 이 시간까지만 가져오기 LocalDateTime now = LocalDateTime.now(); LocalDateTime after24Hours = now.plusHours(24); List walkInvitations = walkInvitationRepository.findAllByWalkStartDateTimeBetween(now, after24Hours); - return HomePageResponseDto.getListFrom(walkInvitations); + if(walkInvitations.isEmpty()){ + throw new NoSuchElementException("홈 화면에 불러올 글이 없습니다"); + } + + return getHomePageResponseDtoList(walkInvitations); + } + + + /** + * + * 포맷 변환 등 메서드 모음 + */ + public String formatLocalDateTime(LocalDateTime dateTime) { + DateTimeFormatter dayMonthFormatter = DateTimeFormatter.ofPattern("M/d"); + String dayMonth = dateTime.format(dayMonthFormatter); + + String dayOfWeek = dateTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.KOREAN); + + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH시mm분"); + String time = dateTime.format(timeFormatter); + + return String.format("%s(%s) %s ~", dayMonth, dayOfWeek, time); + } + + public String getTimeDifference(LocalDateTime postTime, LocalDateTime currentTime){ + Duration duration = Duration.between(postTime, currentTime); + long minutes = Math.abs(duration.toMinutes()); + String timeDifference; + + if (minutes < 60) { + timeDifference = minutes + "분 전"; + } else { + long hours = Math.abs(duration.toHours()); + timeDifference = hours + "시간 전"; + } + + return timeDifference; + } + + /** + * + * DTO <-> 엔티티 변환 메서드 모음 + */ + public WalkInvitationDetailsResponseDto getWalkInvitationDetailsResponseDto(WalkInvitation walkInvitation, List photoUrls, Member member){ + return WalkInvitationDetailsResponseDto.builder() + .title(walkInvitation.getTitle()) + .content(walkInvitation.getContent()) + .latitude(walkInvitation.getLatitude()) + .longitude(walkInvitation.getLongitude()) + .detailedLocation(walkInvitation.getDetailedLocation()) + .walkDateTime(formatLocalDateTime(walkInvitation.getWalkStartDateTime())) + .walkingStatus(walkInvitation.getWalkingStatus().toString()) + .walkInvitationPhotoUrls(photoUrls) + .memberId(member.getId()) + .memberName(member.getNickName()) + .memberPhotoUrl(member.getPhotoUrl()) + .build(); + } + + public List getHomePageResponseDtoList(List walkInvitations){ + return walkInvitations.stream().map(walkInvitation -> { + return HomePageResponseDto.builder() + .id(walkInvitation.getId()) + .title(walkInvitation.getTitle()) + .latitude(walkInvitation.getLatitude()) + .longitude(walkInvitation.getLongitude()) + .detailedLocation(walkInvitation.getDetailedLocation()) + .walkDateTime(formatLocalDateTime(walkInvitation.getWalkStartDateTime())) + .walkingStatus(walkInvitation.getWalkingStatus()) + .walkInvitationPhotoUrl(walkInvitation.getPhotoUrls().get(0).getPhotoUrl()) + .timeDifference(getTimeDifference(walkInvitation.getWalkStartDateTime(), LocalDateTime.now())) + .build(); + }).toList(); } } diff --git a/src/main/java/com/gdsc/petwalk/global/exception/ExControllerAdvice.java b/src/main/java/com/gdsc/petwalk/global/exception/ExControllerAdvice.java index b59bdce..c4b3665 100644 --- a/src/main/java/com/gdsc/petwalk/global/exception/ExControllerAdvice.java +++ b/src/main/java/com/gdsc/petwalk/global/exception/ExControllerAdvice.java @@ -10,18 +10,47 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.multipart.support.MissingServletRequestPartException; +import java.time.format.DateTimeParseException; +import java.util.NoSuchElementException; import java.util.stream.Collectors; @RestControllerAdvice @Slf4j public class ExControllerAdvice { + // 클라이언트의 요청이 잘못 됨. dto 이름이나 양식 등 + @ExceptionHandler(MissingServletRequestPartException.class) + public ResponseEntity handleMissingServletRequestPartException(MissingServletRequestPartException e){ + log.info("Request 요청 관련 오류"); + ExceptionDto exceptionDto = ExceptionDto.builder() + .status(false) + .message(e.getMessage()) + .errorCode(HttpStatus.BAD_REQUEST.toString()) + .build(); + + return ResponseEntity.badRequest().body(exceptionDto); + } + + @ExceptionHandler(DateTimeParseException.class) + public ResponseEntity DateTimeParseException(DateTimeParseException e){ + log.info("LocalDateTime의 형식이 잘 못 되었습니다"); + ExceptionDto exceptionDto = ExceptionDto.builder() + .status(false) + .message(e.getMessage()) + .errorCode(HttpStatus.BAD_REQUEST.toString()) + .build(); + + return ResponseEntity.badRequest().body(exceptionDto); + } + // 컨트롤러 단에서 발생하는 예외 처리 @ExceptionHandler(MemberException.class) public ResponseEntity DuplicateEmailException(MemberException e){ log.info("Email 중복 오류 예외 핸들러 발생"); ExceptionDto exceptionDto = ExceptionDto.builder() + .status(false) .message(e.getErrorCode().getMessage()) .errorCode(e.getErrorCode().getHttpStatus().toString()) .build(); @@ -33,6 +62,7 @@ public ResponseEntity DuplicateEmailException(MemberException e){ public ResponseEntity NotValidEmailException(MethodArgumentNotValidException e){ log.info("회원가입 시 형식 오류 예외 핸들러 발생"); ExceptionDto exceptionDto = ExceptionDto.builder() + .status(false) .message(e.getBindingResult().getFieldErrors().get(0).getDefaultMessage()) .errorCode(e.getStatusCode().toString()) .build(); @@ -44,6 +74,7 @@ public ResponseEntity NotValidEmailException(MethodArgumentNotVali public ResponseEntity UsernameNotFoundException(UsernameNotFoundException e){ log.info("DB에서 유저 조회 시 예외 핸들러 발생"); ExceptionDto exceptionDto = ExceptionDto.builder() + .status(false) .message(e.getMessage()) .errorCode(HttpStatus.BAD_REQUEST.toString()) .build(); @@ -51,4 +82,16 @@ public ResponseEntity UsernameNotFoundException(UsernameNotFoundEx return ResponseEntity.badRequest().body(exceptionDto); } + @ExceptionHandler(NoSuchElementException.class) + public ResponseEntity NoSuchElementException(NoSuchElementException e){ + log.info("DB에서 엔티티 조회 시 예외 핸들러 발생"); + ExceptionDto exceptionDto = ExceptionDto.builder() + .status(false) + .message(e.getMessage()) + .errorCode(HttpStatus.NOT_FOUND.toString()) + .build(); + + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(exceptionDto); + } + } diff --git a/src/main/java/com/gdsc/petwalk/global/exception/dto/ExceptionDto.java b/src/main/java/com/gdsc/petwalk/global/exception/dto/ExceptionDto.java index c4b0760..a85019b 100644 --- a/src/main/java/com/gdsc/petwalk/global/exception/dto/ExceptionDto.java +++ b/src/main/java/com/gdsc/petwalk/global/exception/dto/ExceptionDto.java @@ -6,11 +6,13 @@ @Getter public class ExceptionDto { + private boolean status; private String message; private String errorCode; @Builder - public ExceptionDto(String message, String errorCode) { + public ExceptionDto(boolean status, String message, String errorCode) { + this.status = status; this.message = message; this.errorCode = errorCode; }