Skip to content

Commit 1fee4d8

Browse files
authored
Merge pull request #1 from donghyuun/format
merge: 에러 핸들링 및 리팩토링
2 parents 38090ce + 63c93f5 commit 1fee4d8

32 files changed

Lines changed: 539 additions & 163 deletions

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,11 @@ application.properties
4141
application.yml
4242

4343
### firebase
44-
firebase-service-key.json
44+
firebase-service-key.json
45+
/src/main/generated/com/example/busnotice/domain/bus/QBus.java
46+
/src/main/generated/com/example/busnotice/domain/busStop/QBusStop.java
47+
/src/main/generated/com/example/busnotice/domain/busStop/QCityCode.java
48+
/src/main/generated/com/example/busnotice/domain/user/QUser.java
49+
/src/main/generated/com/example/busnotice/domain/fcmToken/QFCMToken.java
50+
/src/main/generated/com/example/busnotice/domain/user/QRefreshToken.java
51+
/src/main/generated/com/example/busnotice/domain/schedule/QSchedule.java

build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ repositories {
2929

3030
dependencies {
3131
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
32-
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
3332
implementation 'org.springframework.boot:spring-boot-starter-web'
3433
testImplementation 'junit:junit:4.13.1'
3534
compileOnly 'org.projectlombok:lombok'
@@ -83,6 +82,13 @@ dependencies {
8382
// Firebase
8483
implementation 'com.google.firebase:firebase-admin:9.2.0'
8584

85+
// Mail
86+
implementation 'org.springframework.boot:spring-boot-starter-mail'
87+
88+
// Thymeleaf(for email service)
89+
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
90+
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
91+
8692
}
8793
// Querydsl 설정부
8894
def generated = 'src/main/generated'

src/main/java/com/example/busnotice/domain/bus/BusController.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import com.example.busnotice.global.code.StatusCode;
77
import com.example.busnotice.global.format.ApiResponse;
88
import io.swagger.v3.oas.annotations.Operation;
9+
import io.swagger.v3.oas.annotations.media.Content;
10+
import io.swagger.v3.oas.annotations.media.Schema;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
912
import io.swagger.v3.oas.annotations.tags.Tag;
1013
import java.io.UnsupportedEncodingException;
1114
import java.util.List;
@@ -22,13 +25,12 @@
2225
public class BusController {
2326

2427
private final BusService busService;
25-
private final CityCodeRepository cityCodeRepository;
2628

29+
@GetMapping("/nodes/arrive/info")
2730
@Operation(
2831
summary = "특정 노드에 도착 예정인 모든 버스 정보 조회",
2932
description = "도착 예정인 버스가 없는 경우 빈 리스트를 반환"
3033
)
31-
@GetMapping("/nodes/arrive/info")
3234
public ApiResponse<List<Item>> getNodeArriveInfo(
3335
@RequestParam("cityName") String cityName, // 도시 코드
3436
@RequestParam("nodeId") String nodeId // 노드 ID
@@ -73,6 +75,6 @@ public ApiResponse<String> getBusNamesOfNode(
7375
boolean isValid = busNames.containsAll(busList.stream().map(String::trim).toList());
7476
return isValid
7577
? ApiResponse.createSuccess("올바른 버스 목록입니다.")
76-
: ApiResponse.createFail(StatusCode.BAD_REQUEST, "해당 정류장에 속한 버스 노선이 아닙니다.");
78+
: ApiResponse.createSuccess("해당 정류장에 속한 버스 노선이 아닙니다.");
7779
}
7880
}

src/main/java/com/example/busnotice/domain/bus/BusService.java

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ public class BusService {
5555
.bodyToMono(SeoulBusArrInfosDto.class).block();
5656
System.out.println("(서울)특정_노드_ID에_도착하는_모든_버스들_정보_조회: " + result.toString());
5757

58+
if (result.getMsgBody().getItemList() == null) {
59+
return Collections.emptyList();
60+
}
61+
5862
List<SeoulBusArrInfosDto.Item> itemList = result.getMsgBody().getItemList();
5963
List<Item> items = itemList.stream().map(i -> i.toGeneralItem())
6064
.filter(Objects::nonNull).sorted(Comparator.comparingInt(Item::getArrtime))
@@ -77,21 +81,20 @@ public class BusService {
7781
BusArrInfosDto result = webClient.get().uri(uri).retrieve()
7882
.bodyToMono(BusArrInfosDto.class).block();
7983
System.out.println("(전국)특정_노드_ID에_도착하는_모든_버스들_정보_조회: " + result.toString());
80-
if (result != null && result.getResponse() != null && result.getResponse().getBody() != null
81-
&& result.getResponse().getBody().getItems() != null) {
82-
83-
List<BusArrInfosDto.Item> items = result.getResponse().getBody().getItems()
84-
.getItem()
85-
.stream()
86-
.map(item -> {
87-
item.setRoutetp( item.getRoutetp().substring(0, 2));
88-
return item;
89-
})
90-
.toList();
9184

92-
return items;
85+
if (result.getResponse().getBody().getItems() == null) {
86+
return Collections.emptyList();
9387
}
94-
return Collections.emptyList();
88+
89+
List<BusArrInfosDto.Item> items = result.getResponse().getBody().getItems()
90+
.getItem()
91+
.stream()
92+
.map(item -> {
93+
item.setRoutetp(item.getRoutetp().substring(0, 2));
94+
return item;
95+
})
96+
.toList();
97+
return items;
9598
}
9699

97100
public List<Item> 특정_노드_ID에_도착하는_특정_버스들_정보_조회(String cityName, String nodeId,
@@ -145,25 +148,45 @@ public class BusService {
145148
log.info("SeoulBusInfosDto: {}", result);
146149
List<BusRoute> busRoutes = result.getMsgBody().getItemList();
147150
if (busRoutes == null || busRoutes.isEmpty()) {
148-
throw new BusStopException(StatusCode.NOT_FOUND,
149-
"해당 버스정류장을 경유하는 버스 노선이 존재하지 않습니다. 버스정류장 노드 ID 를 다시 확인해주세요.");
151+
return Collections.emptyList();
150152
}
151153
List<BusNameAndTypeResponse> list = result.getMsgBody().getItemList().stream()
152154
.map(i -> {
153155
String routeType = "";
154156
switch (i.getBusRouteType()) {
155-
case 1: routeType = "공항"; break;
156-
case 2: routeType = "마을"; break;
157-
case 3: routeType = "간선"; break;
158-
case 4: routeType = "지선"; break;
159-
case 5: routeType = "순환"; break;
160-
case 6: routeType = "광역"; break;
161-
case 7: routeType = "인천"; break;
162-
case 8: routeType = "경기"; break;
163-
case 9: routeType = "폐지"; break;
164-
case 0: routeType = "공용"; break;
165-
default: routeType = "알수없음"; // 예외 처리
166-
}
157+
case 1:
158+
routeType = "공항";
159+
break;
160+
case 2:
161+
routeType = "마을";
162+
break;
163+
case 3:
164+
routeType = "간선";
165+
break;
166+
case 4:
167+
routeType = "지선";
168+
break;
169+
case 5:
170+
routeType = "순환";
171+
break;
172+
case 6:
173+
routeType = "광역";
174+
break;
175+
case 7:
176+
routeType = "인천";
177+
break;
178+
case 8:
179+
routeType = "경기";
180+
break;
181+
case 9:
182+
routeType = "폐지";
183+
break;
184+
case 0:
185+
routeType = "공용";
186+
break;
187+
default:
188+
routeType = "알수없음"; // 예외 처리
189+
}
167190
return new BusNameAndTypeResponse(i.getBusRouteNm(), routeType);
168191
}
169192
).toList();
@@ -187,13 +210,13 @@ public class BusService {
187210

188211
if (result.getResponse().getBody().getItems().getItem() == null || result.getResponse()
189212
.getBody().getItems().getItem().isEmpty()) {
190-
throw new BusStopException(StatusCode.NOT_FOUND,
191-
"해당 버스정류장을 경유하는 버스 노선이 존재하지 않습니다. 버스정류장 노드 ID 를 다시 확인해주세요.");
213+
return Collections.emptyList();
192214
}
193215

194216
// routeno 리스트 추출
195-
List<BusNameAndTypeResponse> list = result.getResponse().getBody().getItems().getItem().stream()
196-
.map(i -> new BusNameAndTypeResponse(i.getRouteNo(),i.getRouteTp().substring(0, 2))
217+
List<BusNameAndTypeResponse> list = result.getResponse().getBody().getItems().getItem()
218+
.stream()
219+
.map(i -> new BusNameAndTypeResponse(i.getRouteNo(), i.getRouteTp().substring(0, 2))
197220
).toList();
198221
return list;
199222
}

src/main/java/com/example/busnotice/domain/busStop/BusStopController.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import com.example.busnotice.domain.bus.res.BusInfosResponse;
44
import com.example.busnotice.global.format.ApiResponse;
55
import io.swagger.v3.oas.annotations.Operation;
6+
import io.swagger.v3.oas.annotations.media.Content;
7+
import io.swagger.v3.oas.annotations.media.Schema;
8+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
69
import io.swagger.v3.oas.annotations.tags.Tag;
710
import java.io.IOException;
811
import java.util.List;
@@ -22,13 +25,19 @@ public class BusStopController {
2225

2326
@GetMapping("/cityCode")
2427
@Operation(summary = "도시 이름으로 도시 코드 조회")
28+
@ApiResponses({
29+
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "CITY_CODE401", description = "해당 이름과 매칭되는 도시코드가 존재하지 않습니다."),
30+
})
2531
public ApiResponse<String> getCityCode(@RequestParam("cityName") String cityName) {
2632
String cityCodes = busStopService.도시코드_DB_조회(cityName);
2733
return ApiResponse.createSuccessWithData(cityCodes, "도시코드 조회에 성공했습니다.");
2834
}
2935

3036
@GetMapping("/nodes/id")
3137
@Operation(summary = "정류소의 노드 ID 조회")
38+
@ApiResponses({
39+
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "BUS_STOP401", description = "해당 이름을 포함하는 버스정류장이 존재하지 않습니다."),
40+
})
3241
public ApiResponse<String> getNodeId
3342
(
3443
@RequestParam("cityName") String cityName, // 도시 이름
@@ -48,7 +57,8 @@ public ApiResponse<String> getCityCode(@RequestParam("cityName") String cityName
4857
) throws IOException {
4958
List<String> busNames = busStopService.해당_이름을_포함하는_버스정류장_목록_조회_이름만_반환(cityName,
5059
busStopName);
51-
return ApiResponse.createSuccessWithData(busNames, "해당 이름을 포함하는 버스정류장 목록(이름) 조회에 성공했습니다.");
60+
String msg = busNames.isEmpty() ? "해당 이름을 포함하는 버스정류장이 존재하지 않습니다" : "해당 이름을 포함하는 버스정류장이 존재합니다.";
61+
return ApiResponse.createSuccessWithData(busNames, msg);
5262
}
5363

5464
@GetMapping("/nodes/infos")
@@ -61,7 +71,8 @@ public ApiResponse<String> getCityCode(@RequestParam("cityName") String cityName
6171
BusInfosResponse busInfosResponse = busStopService.해당_이름을_포함하는_버스정류장_목록_조회_모든_정보_반환(
6272
cityName,
6373
busStopName);
74+
String msg = busInfosResponse.busInfosResponse().isEmpty() ? "해당 이름을 포함하는 버스정류장이 존재하지 않습니다" : "해당 이름을 포함하는 버스정류장이 존재합니다.";
6475
return ApiResponse.createSuccessWithData(busInfosResponse,
65-
"해당 이름을 포함하는 버스정류장 목록(모든 정보) 조회에 성공했습니다.");
76+
msg);
6677
}
6778
}

src/main/java/com/example/busnotice/domain/busStop/BusStopService.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.example.busnotice.domain.busStop.res.BusStopsDto.Item;
77
import com.example.busnotice.domain.busStop.res.BusStopsDto.Items;
88
import com.example.busnotice.domain.busStop.res.SeoulBusStopsDto;
9+
import com.example.busnotice.global.code.ErrorCode;
910
import com.example.busnotice.global.code.StatusCode;
1011
import com.example.busnotice.global.exception.BusStopException;
1112
import com.example.busnotice.global.exception.GeneralException;
@@ -16,6 +17,7 @@
1617
import java.net.URI;
1718
import java.net.URLEncoder;
1819
import java.nio.charset.StandardCharsets;
20+
import java.util.Collections;
1921
import java.util.List;
2022
import lombok.RequiredArgsConstructor;
2123
import lombok.extern.slf4j.Slf4j;
@@ -75,19 +77,19 @@ public class BusStopService {
7577
}
7678
String cityCode = result.toString().trim();
7779
if (cityCode == null || cityCode.isEmpty()) {
78-
throw new GeneralException(StatusCode.BAD_REQUEST, "도시 코드 조회에 실패했습니다.");
80+
throw new GeneralException(ErrorCode.CITY_CODE_NOT_FOUND);
7981
}
8082
return result.toString().trim();
8183
} catch (Exception e) {
8284
e.printStackTrace();
83-
throw new GeneralException(StatusCode.INTERNAL_SERVER_ERROR, "도시 코드 조회에 실패했습니다.");
85+
throw new GeneralException(ErrorCode.CITY_CODE_NOT_FOUND);
8486
}
8587
}
8688

8789
@Cacheable(value = "cityCodes", key = "#p0")
8890
public String 도시코드_DB_조회(String cityName) {
8991
String cityCode = cityCodeRepository.findByName(cityName.trim())
90-
.orElseThrow(() -> new GeneralException(StatusCode.BAD_REQUEST, "해당 지역이 존재하지 않습니다."))
92+
.orElseThrow(() -> new GeneralException(ErrorCode.CITY_CODE_NOT_FOUND))
9193
.getCode();
9294

9395
return cityCode;
@@ -116,7 +118,7 @@ public class BusStopService {
116118
System.out.println("response.toString() = " + response.toString());
117119
if (response.getMsgBody().getItemList() == null || response.getMsgBody().getItemList()
118120
.isEmpty()) {
119-
throw new BusStopException(StatusCode.NOT_FOUND, "해당 이름을 포함하는 버스정류장이 존재하지 않습니다.");
121+
return Collections.emptyList();
120122
}
121123
List<String> busNames = response.getMsgBody().getItemList().stream()
122124
.map(item -> item.getStNm()).toList();
@@ -147,7 +149,7 @@ public class BusStopService {
147149
System.out.println("result.toString() = " + result.toString());
148150
Items items = result.getResponse().getBody().getItems();
149151
if (items == null || items.getItem().isEmpty()) {
150-
throw new BusStopException(StatusCode.NOT_FOUND, "해당 이름을 포함하는 버스정류장이 존재하지 않습니다.");
152+
return Collections.emptyList();
151153
}
152154
List<Item> itemsList = items.getItem();
153155
return itemsList.stream().map(item -> item.getNodenm()).toList();
@@ -176,7 +178,7 @@ public class BusStopService {
176178
System.out.println("response.toString() = " + response.toString());
177179
if (response.getMsgBody().getItemList() == null || response.getMsgBody().getItemList()
178180
.isEmpty()) {
179-
throw new BusStopException(StatusCode.NOT_FOUND, "해당 이름을 포함하는 버스정류장이 존재하지 않습니다.");
181+
return new BusInfosResponse(Collections.emptyList());
180182
}
181183
List<BusInfoResponse> busInfoResponses = response.getMsgBody().getItemList().stream()
182184
.map(item -> new BusInfoResponse(item.getStNm(), item.getArsId(),
@@ -207,9 +209,11 @@ public class BusStopService {
207209
.block();
208210
System.out.println("result.toString() = " + result.toString());
209211
Items items = result.getResponse().getBody().getItems();
212+
// 해당 하는 버스정류장이 없는 경우
210213
if (items == null || items.getItem().isEmpty()) {
211-
throw new BusStopException(StatusCode.NOT_FOUND, "해당 이름을 포함하는 버스정류장이 존재하지 않습니다.");
214+
return new BusInfosResponse(Collections.emptyList());
212215
}
216+
// 해당 하는 버스정류장이 존재하는 경우
213217
List<Item> itemsList = items.getItem();
214218
List<BusInfoResponse> busInfoResponses = itemsList.stream()
215219
.map(item -> new BusInfoResponse(item.getNodenm(), item.getNodeid(),
@@ -241,7 +245,7 @@ public class BusStopService {
241245
System.out.println("response.toString() = " + response.toString());
242246
if (response.getMsgBody().getItemList() == null || response.getMsgBody().getItemList()
243247
.isEmpty()) {
244-
throw new BusStopException(StatusCode.NOT_FOUND, "해당 이름을 포함하는 버스정류장이 존재하지 않습니다.");
248+
throw new BusStopException(ErrorCode.BUS_STOP_NOT_FOUND);
245249
}
246250
String nodeId = response.getMsgBody().getItemList().get(0).getArsId();
247251
return nodeId;
@@ -269,7 +273,7 @@ public class BusStopService {
269273
System.out.println("result.toString() = " + result.toString());
270274
Items items = result.getResponse().getBody().getItems();
271275
if (items == null || items.getItem().isEmpty()) {
272-
throw new BusStopException(StatusCode.NOT_FOUND, "해당 이름을 포함하는 버스정류장이 존재하지 않습니다.");
276+
throw new BusStopException(ErrorCode.BUS_STOP_NOT_FOUND);
273277
}
274278
List<Item> itemsList = items.getItem();
275279
return itemsList.get(0).getNodeid();

src/main/java/com/example/busnotice/domain/fcmToken/FCMService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.example.busnotice.domain.schedule.res.ScheduleResponses.BusInfoDto;
99
import com.example.busnotice.domain.user.User;
1010
import com.example.busnotice.domain.user.UserRepository;
11+
import com.example.busnotice.global.code.ErrorCode;
1112
import com.example.busnotice.global.code.StatusCode;
1213
import com.example.busnotice.global.exception.UserException;
1314
import com.google.firebase.messaging.FirebaseMessaging;
@@ -37,7 +38,7 @@ public class FCMService {
3738
@Transactional
3839
public void createFCMToken(Long userId, CreateFCMTokenRequest createFCMTokenRequest) {
3940
User user = userRepository.findById(userId).orElseThrow(
40-
() -> new UserException(StatusCode.NOT_FOUND, "해당 ID 의 유저가 존재하지 않습니다.")
41+
() -> new UserException(ErrorCode.USER_NOT_FOUND)
4142
);
4243

4344
Optional<FCMToken> optionalFCMToken = fcmRepository.findByUser(user);

0 commit comments

Comments
 (0)