From 08fb4378088b38c889254d33ff59426e53a31f6d Mon Sep 17 00:00:00 2001 From: Kim-Dong-Jun99 Date: Wed, 10 Jan 2024 15:40:30 +0900 Subject: [PATCH] =?UTF-8?q?Feat=20:=20STOMP=201=EC=B0=A8=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .http/NaverMap.http | 2 +- .http/Odsay.http | 7 +++++++ .json/AddTripItems.json | 8 +++++++ .json/GetPathAndItems.json | 3 +++ .json/TripItemPriceUpdateMsg.json | 3 +++ .json/TripItemTransportationUpdateMsg.json | 3 +++ .json/TripItemVistDateUpdateMsg.json | 3 +++ .json/UpdateTripItemOrder.json | 21 +++++++++++++++++++ .../trip/dto/response/TripPathInfoMsg.java | 2 +- .../tentenstomp/domain/trip/entity/Trip.java | 6 +++--- .../trip/repository/TripRepository.java | 6 ++++++ .../domain/trip/service/TripItemService.java | 19 +++++++---------- .../domain/trip/service/TripService.java | 10 +++++---- .../global/component/NaverMapComponent.java | 9 ++++---- .../global/component/OdsayComponent.java | 7 +++---- .../global/component/PathComponent.java | 12 +++++------ .../response/TripPathCalculationResult.java | 2 +- .../global/converter/MapConverter.java | 6 +++--- 18 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 .json/AddTripItems.json create mode 100644 .json/GetPathAndItems.json create mode 100644 .json/TripItemPriceUpdateMsg.json create mode 100644 .json/TripItemTransportationUpdateMsg.json create mode 100644 .json/TripItemVistDateUpdateMsg.json create mode 100644 .json/UpdateTripItemOrder.json diff --git a/.http/NaverMap.http b/.http/NaverMap.http index 2f8a54f..187f53b 100644 --- a/.http/NaverMap.http +++ b/.http/NaverMap.http @@ -5,6 +5,6 @@ X-NCP-APIGW-API-KEY: {{naver-map-client-secret}} ### 자동차 경로 계산 api -GET https://naveropenapi.apigw.ntruss.com/map-direction-15/v1/driving?start=127.1058342,37.359708&goal=126.9284261,37.5258975 +GET https://naveropenapi.apigw.ntruss.com/map-direction-15/v1/driving?start=128.5175868107,36.5376537450&goal=128.5163479914,36.5390674494 X-NCP-APIGW-API-KEY-ID: {{naver-map-client-id}} X-NCP-APIGW-API-KEY: {{naver-map-client-secret}} \ No newline at end of file diff --git a/.http/Odsay.http b/.http/Odsay.http index dbc5446..4bcb3ad 100644 --- a/.http/Odsay.http +++ b/.http/Odsay.http @@ -11,3 +11,10 @@ Origin: https://weplanplans.site GET https://api.odsay.com/v1/api/searchPubTransPathT?apiKey={{odsay-key}}&SX=127.1051573&SY=37.3718141&EX=227.124206&EY=37.495701 Origin: https://weplanplans.site +### 대중교통 길 찾기 +GET https://api.odsay.com/v1/api/searchPubTransPathT?apiKey={{odsay-key}}&SX=128.5163479914&SY=36.5390674494&EX=128.5163479914&EY=36.5390674494 +Origin: https://weplanplans.site + +### 대중교통 길 찾기 +GET https://api.odsay.com/v1/api/searchPubTransPathT?apiKey={{odsay-key}}&SX=128.5163479914&SY=36.5390674494&EX=128.3383767680&EY=38.0731872541 +Origin: https://weplanplans.site \ No newline at end of file diff --git a/.json/AddTripItems.json b/.json/AddTripItems.json new file mode 100644 index 0000000..7adb6e7 --- /dev/null +++ b/.json/AddTripItems.json @@ -0,0 +1,8 @@ +{ + "visitDate": "2024-01-04", + "newTripItems": [ + { + "tourItemId": 72 + } + ] +} \ No newline at end of file diff --git a/.json/GetPathAndItems.json b/.json/GetPathAndItems.json new file mode 100644 index 0000000..874f2ef --- /dev/null +++ b/.json/GetPathAndItems.json @@ -0,0 +1,3 @@ +{ + "visitDate": "2024-01-03" +} \ No newline at end of file diff --git a/.json/TripItemPriceUpdateMsg.json b/.json/TripItemPriceUpdateMsg.json new file mode 100644 index 0000000..14d023f --- /dev/null +++ b/.json/TripItemPriceUpdateMsg.json @@ -0,0 +1,3 @@ +{ + "price": 50000 +} \ No newline at end of file diff --git a/.json/TripItemTransportationUpdateMsg.json b/.json/TripItemTransportationUpdateMsg.json new file mode 100644 index 0000000..8838697 --- /dev/null +++ b/.json/TripItemTransportationUpdateMsg.json @@ -0,0 +1,3 @@ +{ + "transportation": "CAR" +} \ No newline at end of file diff --git a/.json/TripItemVistDateUpdateMsg.json b/.json/TripItemVistDateUpdateMsg.json new file mode 100644 index 0000000..3cad74e --- /dev/null +++ b/.json/TripItemVistDateUpdateMsg.json @@ -0,0 +1,3 @@ +{ + "visitDate": "2024-01-04" +} \ No newline at end of file diff --git a/.json/UpdateTripItemOrder.json b/.json/UpdateTripItemOrder.json new file mode 100644 index 0000000..d33b99a --- /dev/null +++ b/.json/UpdateTripItemOrder.json @@ -0,0 +1,21 @@ +{ + "visitDate": "2024-01-03", + "tripItemOrder": [ + { + "tripItemId": 1, + "seqNum": 3 + }, + { + "tripItemId": 3, + "seqNum": 4 + }, + { + "tripItemId": 4, + "seqNum": 1 + }, + { + "tripItemId": 6, + "seqNum": 2 + } + ] +} \ No newline at end of file diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java index daa826b..19489a4 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java @@ -14,7 +14,7 @@ public record TripPathInfoMsg( ) { public record PathInfo( - Long price, + Integer price, Double totalDistance, Long totalTime ){} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java b/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java index 182d058..53738fe 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java @@ -47,10 +47,10 @@ public class Trip extends BaseTimeEntity { @ColumnDefault("0") private Long tripItemPriceSum; @ColumnDefault("0") - private Long transportationPriceSum; + private Integer transportationPriceSum; @Convert(converter = MapConverter.class) @Column(columnDefinition = "JSON") - private Map tripPathPriceMap; + private Map tripPathPriceMap; @OneToMany(mappedBy = "trip", fetch = LAZY, cascade = REMOVE) private final List tripMembers = new ArrayList<>(); @@ -80,7 +80,7 @@ public TripInfoMsg toTripInfo() { this.getArea(), this.getSubarea(), this.getBudget()); } - public void updateTransportationPriceSum(Long oldVisitDateTransportationPriceSum, Long newVisitDateTransportationPriceSum) { + public void updateTransportationPriceSum(Integer oldVisitDateTransportationPriceSum, Integer newVisitDateTransportationPriceSum) { this.transportationPriceSum -= oldVisitDateTransportationPriceSum; this.transportationPriceSum += newVisitDateTransportationPriceSum; } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/repository/TripRepository.java b/src/main/java/org/tenten/tentenstomp/domain/trip/repository/TripRepository.java index f008fbd..d0a85c2 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/repository/TripRepository.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/repository/TripRepository.java @@ -1,7 +1,13 @@ package org.tenten.tentenstomp.domain.trip.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.tenten.tentenstomp.domain.trip.entity.Trip; +import java.util.Optional; + public interface TripRepository extends JpaRepository { + @Query("SELECT t FROM Trip t JOIN FETCH t.tripItems WHERE t.id = :tripId") + Optional findTripByTripId(@Param("tripId") Long tripId); } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java index 2bba0fa..2b741b8 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java @@ -17,8 +17,6 @@ import org.tenten.tentenstomp.global.component.dto.response.TripPathCalculationResult; import org.tenten.tentenstomp.global.exception.GlobalException; import org.tenten.tentenstomp.global.messaging.kafka.producer.KafkaProducer; -import org.tenten.tentenstomp.global.messaging.redis.publisher.RedisPublisher; -import org.tenten.tentenstomp.global.util.RedisChannelUtil; import java.time.LocalDate; import java.util.ArrayList; @@ -27,7 +25,6 @@ import static org.springframework.http.HttpStatus.NOT_FOUND; import static org.tenten.tentenstomp.global.common.constant.TopicConstant.*; -import static org.tenten.tentenstomp.global.common.constant.TopicConstant.BUDGET; @Service @RequiredArgsConstructor @@ -61,7 +58,7 @@ public void updateTripItemVisitDate(String tripItemId, TripItemVisitDateUpdateMs List newDateTripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), newDate); Long oldSeqNum = tripItem.getSeqNum(); - Long newSeqNum = (long) newDateTripItems.size(); + Long newSeqNum = (long) newDateTripItems.size()+1; List newPastDateTripItems = new ArrayList<>(); for (TripItem pastDateTripItem : pastDateTripItems) { if (pastDateTripItem.getId().equals(tripItem.getId())) { @@ -80,9 +77,9 @@ public void updateTripItemVisitDate(String tripItemId, TripItemVisitDateUpdateMs TripPathCalculationResult pastDateTripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newPastDateTripItems)); TripPathCalculationResult newDateTripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newDateTripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(pastDate.toString(), 0L), pastDateTripPath.pathPriceSum()); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(newDate.toString(), 0L), newDateTripPath.pathPriceSum()); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(pastDate.toString(), 0), pastDateTripPath.pathPriceSum()); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(newDate.toString(), 0), newDateTripPath.pathPriceSum()); tripPathPriceMap.put(pastDate.toString(), pastDateTripPath.pathPriceSum()); tripPathPriceMap.put(newDate.toString(), newDateTripPath.pathPriceSum()); tripRepository.save(trip); @@ -118,8 +115,8 @@ public void deleteTripItem(String tripItemId) { tripItemRepository.delete(tripItem); TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newTripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0L), tripPath.pathPriceSum()); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0), tripPath.pathPriceSum()); tripPathPriceMap.put(visitDate.toString(), tripPath.pathPriceSum()); tripRepository.save(trip); @@ -147,8 +144,8 @@ public void updateTripItemTransportation(String tripItemId, TripItemTransportati tripItemRepository.save(tripItem); TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(tripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0L), tripPath.pathPriceSum()); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0), tripPath.pathPriceSum()); tripPathPriceMap.put(visitDate.toString(), tripPath.pathPriceSum()); tripRepository.save(trip); diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java index 664807a..17487d4 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java @@ -19,11 +19,13 @@ import org.tenten.tentenstomp.global.component.PathComponent; import org.tenten.tentenstomp.global.component.dto.request.TripPlace; import org.tenten.tentenstomp.global.component.dto.response.TripPathCalculationResult; +import org.tenten.tentenstomp.global.exception.GlobalException; import org.tenten.tentenstomp.global.messaging.kafka.producer.KafkaProducer; import java.time.LocalDate; import java.util.*; +import static org.springframework.http.HttpStatus.NOT_FOUND; import static org.tenten.tentenstomp.global.common.constant.TopicConstant.*; @Service @@ -112,8 +114,8 @@ public void addTripItem(String tripId, TripItemAddMsg tripItemAddMsg) { private void updateBudgetAndItemsAndPath(Trip trip, List tripItems, String visitDate) { TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(tripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate, 0L), tripPath.pathPriceSum()); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate, 0), tripPath.pathPriceSum()); tripPathPriceMap.put(visitDate, tripPath.pathPriceSum()); tripRepository.save(trip); @@ -126,7 +128,7 @@ private void updateBudgetAndItemsAndPath(Trip trip, List tripItems, St @Transactional public void updateTripItemOrder(String tripId, TripItemOrderUpdateMsg orderUpdateMsg) { - Trip trip = tripRepository.getReferenceById(Long.parseLong(tripId)); + Trip trip = tripRepository.findTripByTripId(Long.parseLong(tripId)).orElseThrow(() -> new GlobalException("해당 아이디로 존재하는 여정이 없습니다 " + tripId, NOT_FOUND)); Map itemOrderMap = new HashMap<>(); for (OrderInfo orderInfo : orderUpdateMsg.tripItemOrder()) { itemOrderMap.put(orderInfo.tripItemId(), orderInfo.seqNum()); @@ -180,7 +182,7 @@ private void sendToKafkaAndSave(Object... dataArgs) { private TripMemberMsg getTripMemberMsg(String tripId) { Object cached = redisCache.get(MEMBER, tripId); if (cached != null) { - return (TripMemberMsg) cached; + return objectMapper.convertValue(cached, TripMemberMsg.class); } HashMap connectedMemberMap = tripConnectedMemberMap.getOrDefault(tripId, new HashMap<>()); TripMemberMsg tripMemberMsg = new TripMemberMsg( diff --git a/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java b/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java index 354bc88..f699661 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java @@ -6,12 +6,13 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg; import org.tenten.tentenstomp.global.exception.GlobalException; import java.util.List; @@ -19,7 +20,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpStatus.CONFLICT; -import static org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.*; +import static org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.PathInfo; import static org.tenten.tentenstomp.global.common.constant.NaverMapConstant.NAVER_MAP_API_KEY_HEADER; import static org.tenten.tentenstomp.global.common.constant.NaverMapConstant.NAVER_MAP_CLIENT_ID_HEADER; @@ -69,7 +70,7 @@ public PathInfo calculatePathInfo(String fromLongitude, Integer fuelPrice = (Integer) summary.get("fuelPrice"); Integer distance = (Integer) summary.get("distance"); Integer duration = (Integer) summary.get("duration"); - return new PathInfo((long) duration / 60_000 , (double) distance, (long)tollFare + fuelPrice); + return new PathInfo(tollFare + fuelPrice , (double) distance, (long) duration / 60_000); } else { throw new GlobalException("자동차 경로를 조회할 수 없습니다.", CONFLICT); } diff --git a/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java b/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java index 4c232d1..a5befda 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java @@ -13,7 +13,6 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg; import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.PathInfo; import org.tenten.tentenstomp.global.exception.GlobalException; @@ -56,10 +55,10 @@ public PathInfo calculatePathInfo(String fromLongitude, List> pathList = (List>) resultMap.get("path"); Map path = pathList.get(0); Map pathInfo = (Map) path.get("info"); - Integer payment = (Integer) pathInfo.get("payment"); - Double distance = (Double) pathInfo.get("totalDistance"); + Integer payment = (Integer) pathInfo.get("totalPayment"); + Double distance = Double.valueOf(Integer.toString((Integer) pathInfo.get("totalDistance"))); Integer totalTime = (Integer) pathInfo.get("totalTime"); - return new PathInfo((long) totalTime, distance, (long) payment); + return new PathInfo( payment, distance, (long) totalTime); } else { throw new GlobalException("대중교통 경로를 조회할 수 없습니다.", CONFLICT); } diff --git a/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java b/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java index ce375ca..89f0d67 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java @@ -2,18 +2,16 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg; import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.PathInfo; import org.tenten.tentenstomp.global.common.annotation.GetExecutionTime; -import org.tenten.tentenstomp.global.component.dto.request.TripPlace; import org.tenten.tentenstomp.global.component.dto.request.PathCalculateRequest; +import org.tenten.tentenstomp.global.component.dto.request.TripPlace; import org.tenten.tentenstomp.global.component.dto.response.TripPathCalculationResult; import java.util.ArrayList; import java.util.List; -import java.util.stream.Stream; import static org.tenten.tentenstomp.global.common.enums.Transportation.CAR; @@ -23,7 +21,7 @@ public class PathComponent { private final OdsayComponent odsayComponent; private final NaverMapComponent naverMapComponent; - @Async +// @Async public TripPathInfoMsg calculatePath(TripPlace fromPlace, TripPlace toPlace) { long startTime = System.currentTimeMillis(); PathInfo pathInfo; @@ -38,12 +36,14 @@ public TripPathInfoMsg calculatePath(TripPlace fromPlace, TripPlace toPlace) { @GetExecutionTime public TripPathCalculationResult getTripPath(List tripPlaceList) { List pathCalculateRequests = toPathCalculateRequest(tripPlaceList); - long priceSum = 0L; + int priceSum = 0; List pathInfoMsgs = new ArrayList<>(); for (PathCalculateRequest calculateRequest : pathCalculateRequests) { TripPathInfoMsg tripPathInfoMsg = calculatePath(calculateRequest.from(), calculateRequest.to()); pathInfoMsgs.add(tripPathInfoMsg); - priceSum += tripPathInfoMsg.pathInfo().price(); + if (tripPathInfoMsg.pathInfo() != null) { + priceSum += tripPathInfoMsg.pathInfo().price(); + } } return new TripPathCalculationResult(priceSum, pathInfoMsgs); diff --git a/src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathCalculationResult.java b/src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathCalculationResult.java index e4bf4d6..09059ee 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathCalculationResult.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathCalculationResult.java @@ -5,7 +5,7 @@ import java.util.List; public record TripPathCalculationResult( - Long pathPriceSum, + Integer pathPriceSum, List tripPathInfoMsgs ) { } diff --git a/src/main/java/org/tenten/tentenstomp/global/converter/MapConverter.java b/src/main/java/org/tenten/tentenstomp/global/converter/MapConverter.java index 0dbf2a1..2294e41 100644 --- a/src/main/java/org/tenten/tentenstomp/global/converter/MapConverter.java +++ b/src/main/java/org/tenten/tentenstomp/global/converter/MapConverter.java @@ -9,7 +9,7 @@ import java.util.Map; @Converter -public class MapConverter implements AttributeConverter { +public class MapConverter implements AttributeConverter, String> { protected final ObjectMapper objectMapper; public MapConverter() { @@ -28,11 +28,11 @@ public String convertToDatabaseColumn(Map map) { } } @Override - public Map convertToEntityAttribute(String s) { + public Map convertToEntityAttribute(String s) { if (StringUtils.hasText(s)) { try { - return objectMapper.readValue(s, Map.class); // 5 + return (Map) objectMapper.readValue(s, Map.class); // 5 } catch (Exception e) { throw new RuntimeException(e); }