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

반경 내 주차장 조회 기능 구현 #13

Merged
merged 44 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f44658b
feat: jsonProperty 설정
youngh0 Feb 3, 2024
43ca5c9
feat: hibernate 공간 데이터 의존성 추가
youngh0 Feb 3, 2024
85f7423
feat: Location 의 필드를 공간데이터 타입 Point 로 수정
youngh0 Feb 3, 2024
7674fc9
feat: querydsl 의존성 추가
youngh0 Feb 5, 2024
c1fa2c3
feat: querydsl 의존성 제거
youngh0 Feb 6, 2024
ba3c449
feat: 주차장 목록 조회 쿼리 파라미터 전용 argument resolver 구현
youngh0 Feb 6, 2024
97ce588
feat: 반경 내 주차장 조회 쿼리 작성
youngh0 Feb 6, 2024
c4fad88
feat: argument resolver 등록
youngh0 Feb 6, 2024
0372e0d
feat: 반경 내 주차장 조회 controller, service(정렬, 필터링) 구현
youngh0 Feb 6, 2024
d399ab5
feat: builder 추가
youngh0 Feb 6, 2024
3469889
feat: 필터 기능하는 ParkingDomainService 추가
youngh0 Feb 6, 2024
7f49f6d
feat: 사용하지 않는 코드 제거
youngh0 Feb 6, 2024
6288499
feat: conflict 해결
youngh0 Mar 12, 2024
35a5747
Merge remote-tracking branch 'origin/main' into feat/10-find-parkingLots
youngh0 Mar 13, 2024
2d059a8
feat: 사용하지 않는 repository 삭제
youngh0 Mar 13, 2024
592b1c7
feat: 요금 계산 bean 추가
youngh0 Mar 13, 2024
f8b4dbd
feat: 주차장 목록 조회 시 사용자 조회 조건 필터링 구현
youngh0 Mar 13, 2024
d33ee40
feat: 메서드 분리
youngh0 Mar 13, 2024
44ae717
feat: 주차장 도보 예상 시간 로직 테스트 작성
youngh0 Mar 13, 2024
28ce548
refactor: 주석 제거
youngh0 Mar 13, 2024
6b7459f
feat: 주차장 목록 조회 시 조회 조건 엔티티로 대체 가능한 query param 제거
youngh0 Mar 13, 2024
d5ca66d
feat: 주차장 검색 조건 request 생성
youngh0 Mar 21, 2024
4c780fc
feat: 검색 조건 변환 기능 구현
youngh0 Mar 21, 2024
5f608cc
feat: 반경조회 비회원 조회 구현
youngh0 Mar 22, 2024
d008f2e
feat: memberId 아규먼트 리졸버 구현
youngh0 Mar 22, 2024
0035310
feat: feeType 타입 변경
youngh0 Mar 22, 2024
227cf26
feat: enum 의 value list 변환 로직 SearchConditionAvailable 로 이동
youngh0 Mar 27, 2024
a4dc6a1
feat: String 과 일치하는 enum List 변환 로직 SearchConditionAvailable 로 이동
youngh0 Mar 27, 2024
84b1100
feat: find 메서드 구현
youngh0 Mar 27, 2024
2973615
feat: 무료인지 확인하는 메서드 구현
youngh0 Mar 27, 2024
9d03477
feat: 검색조건 유.무료에 맞는 필터링 기능 구현
youngh0 Mar 27, 2024
1f31077
refactor: ParkingDomainService -> ParkingApplicationService 네이밍 변경
youngh0 Mar 27, 2024
6c04212
test: 유.무료 필터링 테스트
youngh0 Mar 27, 2024
b35c425
refactor: 네이밍 수정
youngh0 Mar 27, 2024
f1fa25b
feat: 비회원 기능 회원 인증 시 sessionId null 반환하도록 수정
youngh0 Mar 28, 2024
3b9d046
feat: 불필요한 메서드 제거
youngh0 Mar 28, 2024
9d5693e
Merge remote-tracking branch 'origin/main' into feat/10-find-parkingLots
youngh0 Mar 29, 2024
dfac844
feat: 충돌 해결
youngh0 Mar 29, 2024
4528710
feat: swagger 추가
youngh0 Mar 29, 2024
5362f5d
refactor: 서비스 계층에서 String <-> SearchConditionAvailable Enum 변환 로직 개선
This2sho Apr 1, 2024
03dcdd3
fix: 잘못 사용되고 있는 값 객체 제거
This2sho Apr 1, 2024
fc15e7e
feat: 응답 dto 변환 로직 이동
youngh0 Apr 1, 2024
7b48ca1
refactor: 네이밍 수정
youngh0 Apr 1, 2024
4fe6e61
feat: 현재 시간 변수 생성 위치 수정
youngh0 Apr 3, 2024
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: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.parking.api.parking;

import com.example.parking.application.parking.ParkingService;
import com.example.parking.application.parking.dto.ParkingLotsResponse;
import com.example.parking.application.parking.dto.ParkingQueryRequest;
import com.example.parking.application.parking.dto.ParkingSearchConditionRequest;
import com.example.parking.config.argumentresolver.parking.ParkingMemberId;
import com.example.parking.config.argumentresolver.parking.ParkingQuery;
import com.example.parking.config.argumentresolver.parking.ParkingSearchCondition;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class ParkingController {

private final ParkingService parkingService;

@GetMapping("/parkings")
public ResponseEntity<ParkingLotsResponse> find(
@ParkingQuery ParkingQueryRequest parkingQueryRequest,
@ParkingSearchCondition ParkingSearchConditionRequest parkingSearchConditionRequest,
@ParkingMemberId Long parkingMemberId
) {
ParkingLotsResponse parkingLots = parkingService.findParkingLots(parkingQueryRequest,
parkingSearchConditionRequest, parkingMemberId);
return ResponseEntity.ok(parkingLots);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.example.parking.application.parking;

import com.example.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse;
import com.example.parking.domain.favorite.Favorite;
import com.example.parking.domain.parking.Fee;
import com.example.parking.domain.parking.FilterCondition;
import com.example.parking.domain.parking.Location;
import com.example.parking.domain.parking.Parking;
import com.example.parking.domain.parking.ParkingFeeCalculator;
import com.example.parking.support.Association;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
public class ParkingDomainService {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

먼가 따로 분리해야했을까? 라는 생각이 들긴합니다 ! 이유가 있을까요 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

호이 리뷰에 커멘트 달았슴다~


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParkingDomainService 역할이 짬뽕된거 같아여
이름은 Domain, 어노테이션은 Component라서 도메인 서비스 같아 보이지만
패키지는 application에 있고 반환도 response 반환하고 있어서 어플리케이션 서비스 같이도 보여여
하나로 맞춰주셨으면 합니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조회 조건에 맞게 필터링하는 절차지향적인 로직이라 별도의 Service 를 만들어서 ParkingService 를 조금 더 간결하게 해보려고 했는데 ParkingService 내부 private 메서드로 수정하는게 더 나을까요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일단 제가 의도한건 Application Service 가 더 맞는거같아서 네이밍 수정할게요~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List 을 응답 dto 로 만들기 위해서 예상 요금, 도보 시간 계산, 즐겨 찾기 유무 확인해서 만드는 로직이 절차지향적이라 이 메서드를 ParkingService 의 private 메서드로 옮길지 ParkingApplicationService 에 둘지 계속 고민되네여,, 뭐가 더 괜찮아보이시나여?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

새로 서비스를 나눠서 구현한건 좋은 거 같습니다.
그렇지만, 조회 조건에 맞게 필터링하는 건 ParkingFilterService 같은 도메인 서비스를 두고 ParkingResponse로 변환해주는 코드는 Application Service 내부에 private 메소드로 둬도 괜찮을 거 같아여

private final ParkingFeeCalculator parkingFeeCalculator;

public List<Parking> filterByCondition(List<Parking> parkingLots, FilterCondition filterCondition) {
return parkingLots.stream()
.filter(parking -> parking.containsOperationType(filterCondition.getOperationTypes()))
.filter(parking -> parking.containsParkingType(filterCondition.getParkingTypes()))
.filter(parking -> parking.containsPayType(filterCondition.getPayTypes()))
.toList();
}

public List<ParkingResponse> calculateParkingInfo(List<Parking> parkingLots, int hours,
Location destination, List<Favorite> memberFavorites) {
Set<Long> favoriteParkingIds = extractFavoriteParkingIds(memberFavorites);
return extractParkingInfo(parkingLots, destination, hours, favoriteParkingIds);
}

private List<ParkingResponse> extractParkingInfo(List<Parking> parkingLots, Location destination, int hours,
Set<Long> favoriteParkingIds) {
LocalDateTime now = LocalDateTime.now();

List<ParkingResponse> parkingResponses = new ArrayList<>();
for (Parking parking : parkingLots) {
Fee fee = parkingFeeCalculator.calculateParkingFee(parking, now, now.plusHours(hours));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저의 사랑스러운 아이가 들어가 있군요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

야무지더라구요

int walkingTime = parking.calculateWalkingTime(destination);
ParkingResponse parkingResponse = toParkingResponse(
parking,
fee,
walkingTime,
favoriteParkingIds.contains(parking.getId())
);
parkingResponses.add(parkingResponse);
}
return parkingResponses;
}

private Set<Long> extractFavoriteParkingIds(List<Favorite> memberFavorites) {
return memberFavorites.stream()
.map(Favorite::getParkingId)
.map(Association::getId)
.collect(Collectors.toSet());
}

private ParkingResponse toParkingResponse(Parking parking, Fee fee, int walkingTime, boolean isFavorite) {
return new ParkingResponse(
parking.getId(),
parking.getBaseInformation().getName(),
fee.getFee(),
walkingTime,
parking.getBaseInformation().getParkingType().getDescription(),
isFavorite,
parking.getLocation().getLatitude(),
parking.getLocation().getLongitude()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
package com.example.parking.application.parking;

import com.example.parking.application.parking.dto.ParkingLotsResponse;
import com.example.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse;
import com.example.parking.application.parking.dto.ParkingQueryRequest;
import com.example.parking.application.parking.dto.ParkingSearchConditionRequest;
import com.example.parking.domain.favorite.Favorite;
import com.example.parking.domain.favorite.FavoriteRepository;
import com.example.parking.domain.parking.FilterCondition;
import com.example.parking.domain.parking.Location;
import com.example.parking.domain.parking.OperationType;
import com.example.parking.domain.parking.Parking;
import com.example.parking.domain.parking.ParkingRepository;
import com.example.parking.domain.parking.ParkingType;
import com.example.parking.domain.parking.PayType;
import com.example.parking.domain.parking.repository.ParkingRepository;
import com.example.parking.support.Association;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
Expand All @@ -12,7 +25,58 @@
@Service
public class ParkingService {

private static final String DISTANCE_ORDER_CONDITION = "가까운 순";

private final ParkingRepository parkingRepository;
private final ParkingDomainService parkingDomainService;
private final FavoriteRepository favoriteRepository;

@Transactional(readOnly = true)
public ParkingLotsResponse findParkingLots(ParkingQueryRequest parkingQueryRequest,
ParkingSearchConditionRequest parkingSearchConditionRequest,
Long memberId) {
Location destination = Location.of(parkingQueryRequest.getLongitude(), parkingQueryRequest.getLatitude());
FilterCondition filterCondition = toFilterCondition(parkingSearchConditionRequest);

List<Favorite> favorites = findMemberFavorites(memberId);
List<Parking> parkingLots = findParkingLotsByOrderCondition(parkingSearchConditionRequest.getPriority(),
parkingQueryRequest, destination);

List<Parking> filteredParkingLots = filteringByCondition(parkingLots, filterCondition);
List<ParkingResponse> parkingResponses = parkingDomainService.calculateParkingInfo(filteredParkingLots,
parkingSearchConditionRequest.getHours(), destination, favorites);

return new ParkingLotsResponse(parkingResponses);
}

private FilterCondition toFilterCondition(ParkingSearchConditionRequest parkingSearchConditionRequest) {
List<ParkingType> parkingTypes = ParkingType.collectMatch(parkingSearchConditionRequest.getParkingTypes());
List<OperationType> operationTypes = OperationType.collectMatch(
parkingSearchConditionRequest.getOperationTypes());
List<PayType> payTypes = PayType.collectMatch(parkingSearchConditionRequest.getPayTypes());

return new FilterCondition(operationTypes, parkingTypes, payTypes);
}

private List<Favorite> findMemberFavorites(Long memberId) {
if (memberId == null) {
return Collections.emptyList();
}
return favoriteRepository.findByMemberId(Association.from(memberId));
}

private List<Parking> filteringByCondition(List<Parking> parkingLots, FilterCondition filterCondition) {
return parkingDomainService.filterByCondition(parkingLots, filterCondition);
}

private List<Parking> findParkingLotsByOrderCondition(String priority, ParkingQueryRequest parkingQueryRequest,
Location middleLocation) {
if (priority.equals(DISTANCE_ORDER_CONDITION)) {
return parkingRepository.findAroundParkingLotsOrderByDistance(middleLocation.getPoint(),
parkingQueryRequest.getRadius());
}
return parkingRepository.findAroundParkingLots(middleLocation.getPoint(), parkingQueryRequest.getRadius());
}

@Transactional
public void saveAll(List<Parking> parkingLots) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.parking.application.parking.dto;

import java.util.List;
import lombok.Getter;

@Getter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NoArgsConstructor(access = AccessLevel.PRIVATE)

public class ParkingLotsResponse {

private List<ParkingResponse> parkingLots;

private ParkingLotsResponse() {
}

public ParkingLotsResponse(List<ParkingResponse> parkingLots) {
this.parkingLots = parkingLots;
}

@Getter
public static class ParkingResponse {
private Long parkingId;
private String parkingName;
private Integer estimatedFee;
private Integer estimatedWalkingTime;
private String parkingType;
private Boolean isFavorite;
private Double latitude;
private Double longitude;

private ParkingResponse() {
}

public ParkingResponse(Long parkingId, String parkingName, Integer estimatedFee, Integer estimatedWalkingTime,
String parkingType, Boolean isFavorite, Double latitude, Double longitude) {
this.parkingId = parkingId;
this.parkingName = parkingName;
this.estimatedFee = estimatedFee;
this.estimatedWalkingTime = estimatedWalkingTime;
this.parkingType = parkingType;
this.isFavorite = isFavorite;
this.latitude = latitude;
this.longitude = longitude;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.parking.application.parking.dto;

import lombok.Getter;

@Getter
public class ParkingQueryRequest {

private final Double latitude;
private final Double longitude;
private final Integer radius;

public ParkingQueryRequest(Double latitude, Double longitude, Integer radius) {
this.latitude = latitude;
this.longitude = longitude;
this.radius = radius;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.example.parking.application.parking.dto;

import com.example.parking.domain.parking.OperationType;
import com.example.parking.domain.parking.ParkingType;
import com.example.parking.domain.parking.PayType;
import java.util.List;
import lombok.Getter;

@Getter
public class ParkingSearchConditionRequest {

private static final int BASE_HOURS = 1;
private static final String NOT_FREE = "유료";
private static final String RECOMMEND_ORDER_CONDITION = "추천 순";

private final List<String> operationTypes;
private final List<String> parkingTypes;
private final String feeTypes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유료, 무료 주차장 둘 다 보는 방법은 없는거야?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 제가 놓쳤네염. 감사합니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

적용했습니다~

private final List<String> payTypes;
private final Integer hours;
private final String priority;

public ParkingSearchConditionRequest(List<String> operationTypes, List<String> parkingTypes, String feeTypes,
List<String> payTypes, int hours, String priority) {
this.operationTypes = operationTypes;
this.parkingTypes = parkingTypes;
this.feeTypes = feeTypes;
this.payTypes = payTypes;
this.hours = hours;
this.priority = priority;
}

public static ParkingSearchConditionRequest base() {
return new ParkingSearchConditionRequest(
OperationType.getAllValues(),
ParkingType.getAllValues(),
NOT_FREE,
PayType.getAllValues(),
BASE_HOURS,
RECOMMEND_ORDER_CONDITION
);
}
}
12 changes: 11 additions & 1 deletion src/main/java/com/example/parking/config/WebMvcConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.example.parking.config;

import com.example.parking.config.argumentresolver.AuthArgumentResolver;
import com.example.parking.config.argumentresolver.parking.ParkingMemberIdArgumentResolver;
import com.example.parking.config.argumentresolver.parking.ParkingQueryArgumentResolver;
import com.example.parking.config.argumentresolver.parking.ParkingSearchConditionArgumentResolver;
import com.example.parking.external.config.interceptor.AuthInterceptor;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,19 +18,26 @@ public class WebMvcConfig implements WebMvcConfigurer {

private final AuthInterceptor authInterceptor;
private final AuthArgumentResolver authArgumentResolver;
private final ParkingQueryArgumentResolver parkingQueryArgumentResolver;
private final ParkingSearchConditionArgumentResolver parkingSearchConditionArgumentResolver;
private final ParkingMemberIdArgumentResolver parkingMemberIdArgumentResolver;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(List.of(
"/users",
"/login"
"/login",
"/parkings"
));
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(authArgumentResolver);
resolvers.add(parkingQueryArgumentResolver);
resolvers.add(parkingSearchConditionArgumentResolver);
resolvers.add(parkingMemberIdArgumentResolver);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.parking.config.argumentresolver.parking;

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 ParkingMemberId {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MemberAuth 랑 역할이 동일한거 같은데
무슨 차이인가여?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존의 MemberAuth 는 잘못된 인증 정보면 예외를 던지는데 주차장 조회 기능에선 memberId 가 없으면 즐겨찾기 값을 전부 다 false 로 반환해야됩니다.

그래서 기존 MemberAuth의 잘못된 인증정보 시 예외던지는 코드를 주차장 조회 기능 때문에 null 을 반환하게 하면 MemberAuth 를 사용하고 있는 다른 로직에서 반환된 값의 null 체크를 하고 예외처리를 해야되기 때문에 예외 말고 null 을 반환하도록 새로 만들었습니다.

Copy link
Contributor

@This2sho This2sho Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

같은 목적의 어노테이션을 두개로 늘리기 보다는
아래처럼 필드를 추가해주고

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberAuth {
    boolean required() default true;
}

아규먼트 리졸버에서 required 값을 판단해서 아래처럼 내려주면 될 거 같습니다

@Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        MemberAuth memberAuth = memberAuthFrom(parameter);
        if (memberAuth.required()) {
            String sessionId = webRequest.getHeader(JSESSIONID);
            MemberSession session = authService.findSession(sessionId);
            return session.getMemberId();
        }
        return null;
    }
    
    private MemberAuth memberAuthFrom(MethodParameter parameter) {
        return parameter.getParameterAnnotation(MemberAuth.class);
    }

그러고 회원 정보가 필수가 아닌 컨트롤러에서 적용해주면 될 거 같습니다

@GetMapping("/parkings")
    public ResponseEntity<ParkingLotsResponse> find(
            @ParkingQuery ParkingQueryRequest parkingQueryRequest,
            @ParkingSearchCondition ParkingSearchConditionRequest parkingSearchConditionRequest,
            @MemberAuth(required = false) Long memberId
    ) {
        ParkingLotsResponse parkingLots = parkingService.findParkingLots(parkingQueryRequest,
                parkingSearchConditionRequest, memberId, LocalDateTime.now());
        return ResponseEntity.ok(parkingLots);
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이건 생각 못했는데 아이디어 감사합니다 ㅎ

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.parking.config.argumentresolver.parking;

import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

@Component
public class ParkingMemberIdArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(ParkingMemberId.class);
}

@Override
public Long resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return Long.parseLong(webRequest.getParameter("JSESSIONID"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.parking.config.argumentresolver.parking;

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 ParkingQuery {
}
Loading