Skip to content

Commit e2cd2cc

Browse files
authored
Merge pull request #166 from Myaongi/refactor/#165
refactor/#165 : 게시글 조회 시 AI 이미지 조회되도록 수정
2 parents 841f7a6 + cb59251 commit e2cd2cc

8 files changed

Lines changed: 44 additions & 59 deletions

File tree

src/main/java/Myaong/Gangajikimi/ai/service/AiService.java

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,9 @@ public SimilarityScoreResponse calculateSimilarity(
262262

263263
/**
264264
* 강아지 정보를 바탕으로 AI 이미지를 생성합니다.
265-
* 이미지 바이너리를 Content-Type: image/png 헤더와 함께 반환합니다.
266-
*
267-
* @param request 강아지 정보 요청 (품종, 색상, 특징)
268-
* @return 이미지 바이너리와 헤더를 포함한 ResponseEntity, 실패 시 500 에러 응답
265+
* 실패 시 null을 반환합니다.
269266
*/
270-
public ResponseEntity<byte[]> generateDogImage(DogInfoRequest request) {
267+
public byte[] generateDogImage(DogInfoRequest request) {
271268

272269
final String apiPath = fastApiBaseUrl + "/api/v1/imagegen";
273270

@@ -279,8 +276,8 @@ public ResponseEntity<byte[]> generateDogImage(DogInfoRequest request) {
279276
log.info("AI 이미지 생성 요청 - URL: {}, breed: {}, colors: {}", apiPath, breed, colors);
280277

281278
// 1. HTTP Header 설정 (application/json)
282-
HttpHeaders requestHeaders = new HttpHeaders();
283-
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
279+
HttpHeaders headers = new HttpHeaders();
280+
headers.setContentType(MediaType.APPLICATION_JSON);
284281

285282
// 2. Request Body 생성 (DogInfoRequest 재사용)
286283
DogInfoRequest requestBody = DogInfoRequest.builder()
@@ -289,7 +286,7 @@ public ResponseEntity<byte[]> generateDogImage(DogInfoRequest request) {
289286
.features(features != null ? features : "")
290287
.build();
291288

292-
HttpEntity<DogInfoRequest> requestEntity = new HttpEntity<>(requestBody, requestHeaders);
289+
HttpEntity<DogInfoRequest> requestEntity = new HttpEntity<>(requestBody, headers);
293290

294291
// 3. 이미지 바이너리로 응답 받기
295292
ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity(
@@ -301,25 +298,17 @@ public ResponseEntity<byte[]> generateDogImage(DogInfoRequest request) {
301298
byte[] imageBytes = responseEntity.getBody();
302299
if (imageBytes != null && imageBytes.length > 0) {
303300
log.info("이미지 생성 성공 - breed: {}, imageSize: {} bytes", breed, imageBytes.length);
304-
305-
// 4. 이미지 응답을 위한 헤더 설정
306-
HttpHeaders responseHeaders = new HttpHeaders();
307-
responseHeaders.setContentType(MediaType.IMAGE_PNG);
308-
responseHeaders.setContentLength(imageBytes.length);
309-
310-
return ResponseEntity.ok()
311-
.headers(responseHeaders)
312-
.body(imageBytes);
301+
return imageBytes;
313302
} else {
314303
log.warn("FastAPI 이미지 생성 응답이 비어있습니다 - breed: {}, colors: {}", breed, colors);
315-
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
304+
return null;
316305
}
317306
} catch (RestClientException e) {
318307
log.error("FastAPI 이미지 생성 요청 실패 - breed: {}, error: {}", breed, e.getMessage(), e);
319-
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
308+
return null;
320309
} catch (Exception e) {
321310
log.error("FastAPI 이미지 생성 중 예상치 못한 오류 발생 - breed: {}, error: {}", breed, e.getMessage(), e);
322-
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
311+
return null;
323312
}
324313
}
325314

src/main/java/Myaong/Gangajikimi/ai/web/controller/AiController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import Myaong.Gangajikimi.ai.web.dto.request.DogInfoRequest;
66
import lombok.RequiredArgsConstructor;
77
import org.springframework.http.MediaType;
8-
import org.springframework.http.ResponseEntity;
98
import org.springframework.web.bind.annotation.PostMapping;
109
import org.springframework.web.bind.annotation.RequestBody;
1110
import org.springframework.web.bind.annotation.RequestMapping;
@@ -19,7 +18,7 @@ public class AiController implements AiControllerDocs {
1918
private final AiService aiService;
2019

2120
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
22-
public ResponseEntity<byte[]> createAiImage(@RequestBody DogInfoRequest request) {
21+
public byte[] createAiImage(@RequestBody DogInfoRequest request) {
2322
return aiService.generateDogImage(request);
2423
}
2524
}

src/main/java/Myaong/Gangajikimi/ai/web/docs/AiControllerDocs.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public interface AiControllerDocs {
8686
)
8787
)
8888
})
89-
ResponseEntity<byte[]> createAiImage(
89+
byte[] createAiImage(
9090
@RequestBody(
9191
description = "강아지 정보 (품종, 색상, 특징)",
9292
required = true,

src/main/java/Myaong/Gangajikimi/postfound/service/PostFoundQueryService.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ public PostFoundDetailResponse getPostFoundDetail(Long postId) {
4646
realImageUrls = s3Service.generatePresignedUrls(postFound.getRealImage());
4747
}
4848

49-
// TODO: AI 이미지 생성 로직 구현 후 활성화
50-
// String aiImageUrl = null;
51-
// if (postFound.getAiImage() != null && !postFound.getAiImage().isEmpty()) {
52-
// aiImageUrl = s3Service.generatePresignedUrl(postFound.getAiImage());
53-
// }
49+
String aiImageUrl = null;
50+
if (postFound.getAiImage() != null && !postFound.getAiImage().isEmpty()) {
51+
aiImageUrl = s3Service.generatePresignedUrl(postFound.getAiImage());
52+
}
5453

5554
return PostFoundDetailResponse.of(
5655
postFound.getId(),
@@ -65,8 +64,7 @@ public PostFoundDetailResponse getPostFoundDetail(Long postId) {
6564
postFound.getFoundSpot().getX(), // longitude
6665
postFound.getFoundSpot().getY(), // latitude
6766
postFound.getFoundRegion(), // 행정구역 정보
68-
// TODO: AI 이미지 생성 로직 구현 후 활성화
69-
// aiImageUrl,
67+
aiImageUrl,
7068
realImageUrls,
7169
postFound.getMember().getId(), // authorId
7270
postFound.getMember().getMemberName(),
@@ -97,6 +95,9 @@ public PageResponse getFoundPosts(Integer size, Integer page, FilterRequest requ
9795
if (postFound.getRealImage() != null && !postFound.getRealImage().isEmpty()) {
9896
presignedImageUrl = s3Service.generatePresignedUrl(postFound.getRealImage().get(0));
9997
}
98+
else{
99+
presignedImageUrl = s3Service.generatePresignedUrl(postFound.getAiImage());
100+
}
100101
return PostFoundHomeResponse.of(postFound, presignedImageUrl);
101102
})
102103
.toList();
@@ -122,6 +123,9 @@ public PageResponse getMyFoundPosts(Long memberId, int page, int size) {
122123
if (postFound.getRealImage() != null && !postFound.getRealImage().isEmpty()) {
123124
presignedImageUrl = s3Service.generatePresignedUrl(postFound.getRealImage().get(0));
124125
}
126+
else{
127+
presignedImageUrl = s3Service.generatePresignedUrl(postFound.getAiImage());
128+
}
125129
return PostFoundHomeResponse.of(postFound, presignedImageUrl);
126130
})
127131
.toList();

src/main/java/Myaong/Gangajikimi/postfound/web/docs/PostFoundControllerDocs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ ResponseEntity<GlobalResponse> deleteFound(
297297
"longitude": 127.0276,
298298
"latitude": 37.4979,
299299
"foundRegion": "서울시 서초구",
300+
"aiImage" : "https://s3.amazonaws.com/bucket/presigned-url-example1",
300301
"realImages": [
301302
"https://s3.amazonaws.com/bucket/presigned-url-example1",
302303
"https://s3.amazonaws.com/bucket/presigned-url-example2"

src/main/java/Myaong/Gangajikimi/postfound/web/dto/response/PostFoundDetailResponse.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public class PostFoundDetailResponse {
2727
private Double longitude;
2828
private Double latitude;
2929
private String foundRegion; // 행정구역 정보
30-
// TODO: AI 이미지 생성 로직 구현 후 활성화
31-
// private String aiImage; // AI 생성 이미지 Presigned URL
30+
String aiImage; // AI 생성 이미지 Presigned URL
3231
private List<String> realImages; // 실제 이미지 Presigned URL 목록
3332
private Long authorId;
3433
private String authorName;
@@ -48,8 +47,7 @@ private PostFoundDetailResponse(Long postId,
4847
Double longitude,
4948
Double latitude,
5049
String foundRegion,
51-
// TODO: AI 이미지 생성 로직 구현 후 활성화
52-
// String aiImage,
50+
String aiImage,
5351
List<String> realImages,
5452
Long authorId,
5553
String authorName,
@@ -66,8 +64,7 @@ private PostFoundDetailResponse(Long postId,
6664
this.longitude = longitude;
6765
this.latitude = latitude;
6866
this.foundRegion = foundRegion;
69-
// TODO: AI 이미지 생성 로직 구현 후 활성화
70-
// this.aiImage = aiImage;
67+
this.aiImage = aiImage;
7168
this.realImages = realImages;
7269
this.authorId = authorId;
7370
this.authorName = authorName;
@@ -87,8 +84,7 @@ public static PostFoundDetailResponse of(Long postId,
8784
Double longitude,
8885
Double latitude,
8986
String foundRegion,
90-
// TODO: AI 이미지 생성 로직 구현 후 활성화
91-
// String aiImage,
87+
String aiImage,
9288
List<String> realImages,
9389
Long authorId,
9490
String authorName,
@@ -107,8 +103,7 @@ public static PostFoundDetailResponse of(Long postId,
107103
.longitude(longitude)
108104
.latitude(latitude)
109105
.foundRegion(foundRegion)
110-
// TODO: AI 이미지 생성 로직 구현 후 활성화
111-
// .aiImage(aiImage)
106+
.aiImage(aiImage)
112107
.realImages(realImages)
113108
.authorId(authorId)
114109
.authorName(authorName)

src/main/java/Myaong/Gangajikimi/postlost/service/PostLostQueryService.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,10 @@ public PostLostDetailResponse getPostLostDetail(Long postId) {
5050
realImageUrls = s3Service.generatePresignedUrls(postLost.getRealImage());
5151
}
5252

53-
// TODO: AI 이미지 생성 로직 구현 후 활성화
54-
// String aiImageUrl = null;
55-
// if (postLost.getAiImage() != null && !postLost.getAiImage().isEmpty()) {
56-
// aiImageUrl = s3Service.generatePresignedUrl(postLost.getAiImage());
57-
// }
53+
String aiImageUrl = null;
54+
if (postLost.getAiImage() != null && !postLost.getAiImage().isEmpty()) {
55+
aiImageUrl = s3Service.generatePresignedUrl(postLost.getAiImage());
56+
}
5857

5958
// FixedLocation 조회하여 경도, 위도 배열 생성
6059
List<FixedLocation> fixedLocations = fixedLocationService.findAllByPostLost(postLost);
@@ -81,8 +80,7 @@ public PostLostDetailResponse getPostLostDetail(Long postId) {
8180
postLost.getLostSpot().getX(), // longitude
8281
postLost.getLostSpot().getY(), // latitude
8382
postLost.getLostRegion(), // 행정구역 정보
84-
// TODO: AI 이미지 생성 로직 구현 후 활성화
85-
// aiImageUrl,
83+
aiImageUrl,
8684
realImageUrls,
8785
postLost.getMember().getId(), // authorId
8886
postLost.getMember().getMemberName(),
@@ -106,8 +104,6 @@ public PageResponse getLostPosts(int page, int size, FilterRequest request) {
106104
request.getUserLongitude(),
107105
request.getUserLatitude());
108106

109-
// TODO: 필터링 기능 구현 예정
110-
111107
List<PostLostHomeResponse> lostResponses = lostPosts.getContent().stream()
112108
// PostLost를 PostLostHomeResponse로 변환 (PresignedUrl 포함)
113109
.map(postLost -> {
@@ -116,6 +112,9 @@ public PageResponse getLostPosts(int page, int size, FilterRequest request) {
116112
if (postLost.getRealImage() != null && !postLost.getRealImage().isEmpty()) {
117113
presignedImageUrl = s3Service.generatePresignedUrl(postLost.getRealImage().get(0));
118114
}
115+
else{
116+
presignedImageUrl = s3Service.generatePresignedUrl(postLost.getAiImage());
117+
}
119118
return PostLostHomeResponse.of(postLost, presignedImageUrl);
120119
})
121120
.toList();
@@ -141,6 +140,9 @@ public PageResponse getMyLostPosts(Long memberId, int page, int size) {
141140
if (postLost.getRealImage() != null && !postLost.getRealImage().isEmpty()) {
142141
presignedImageUrl = s3Service.generatePresignedUrl(postLost.getRealImage().get(0));
143142
}
143+
else{
144+
presignedImageUrl = s3Service.generatePresignedUrl(postLost.getAiImage());
145+
}
144146
return PostLostHomeResponse.of(postLost, presignedImageUrl);
145147
})
146148
.toList();

src/main/java/Myaong/Gangajikimi/postlost/web/dto/response/PostLostDetailResponse.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ public class PostLostDetailResponse {
2525
private Double longitude;
2626
private Double latitude;
2727
private String lostRegion; // 행정구역 정보
28-
// TODO: AI 이미지 생성 로직 구현 후 활성화
29-
// private String aiImage; // AI 생성 이미지 Presigned URL
28+
private String aiImage; // AI 생성 이미지 Presigned URL
3029
private List<String> realImages; // 실제 이미지 Presigned URL 목록
3130
private Long authorId;
3231
private String authorName;
@@ -40,8 +39,7 @@ private PostLostDetailResponse(Long postId, String title, String dogName, String
4039
String dogColor, DogGender dogGender, DogStatus dogStatus, String content,
4140
LocalDate lostDate, LocalDateTime lostTime, Double longitude, Double latitude,
4241
String lostRegion,
43-
// TODO: AI 이미지 생성 로직 구현 후 활성화
44-
// String aiImage,
42+
String aiImage,
4543
List<String> realImages,
4644
Long authorId, String authorName,
4745
LocalDateTime createdAt, String timeAgo,
@@ -59,8 +57,7 @@ private PostLostDetailResponse(Long postId, String title, String dogName, String
5957
this.longitude = longitude;
6058
this.latitude = latitude;
6159
this.lostRegion = lostRegion;
62-
// TODO: AI 이미지 생성 로직 구현 후 활성화
63-
// this.aiImage = aiImage;
60+
this.aiImage = aiImage;
6461
this.realImages = realImages;
6562
this.authorId = authorId;
6663
this.authorName = authorName;
@@ -74,8 +71,7 @@ public static PostLostDetailResponse of(Long postId, String title, String dogNam
7471
String dogColor, DogGender dogGender, DogStatus dogStatus, String content,
7572
LocalDate lostDate, LocalDateTime lostTime, Double longitude, Double latitude,
7673
String lostRegion,
77-
// TODO: AI 이미지 생성 로직 구현 후 활성화
78-
// String aiImage,
74+
String aiImage,
7975
List<String> realImages,
8076
Long authorId, String authorName,
8177
LocalDateTime createdAt, String timeAgo,
@@ -94,8 +90,7 @@ public static PostLostDetailResponse of(Long postId, String title, String dogNam
9490
.longitude(longitude)
9591
.latitude(latitude)
9692
.lostRegion(lostRegion)
97-
// TODO: AI 이미지 생성 로직 구현 후 활성화
98-
// .aiImage(aiImage)
93+
.aiImage(aiImage)
9994
.realImages(realImages)
10095
.authorId(authorId)
10196
.authorName(authorName)

0 commit comments

Comments
 (0)