Skip to content

Commit dd6542d

Browse files
authored
Merge pull request #253 from QuokkaJoa/part2-김지협-sprint6
Part2 김지협 sprint6
2 parents e304ecb + 042c83b commit dd6542d

File tree

66 files changed

+2888
-2412
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2888
-2412
lines changed

AssociationMappingInformation.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# 연관관계 매핑 정보
2+
3+
엔티티 관계 : 비교하는 두 엔티티 명
4+
5+
| 엔티티 관계 | 다중성 | 방향성 | 부모-자식 관계 | 연관관계의 주인 |
6+
|:------------------------|:------|:----------------------------|:--------------------------------|:-----------|
7+
| User : UserStatus | 1 : 1 | UserStatus ↔ User 양방향 | 부모 : User, 자식: UserStatus | UserStatus
8+
| User : ReadStatus | 1 : N | ReadStatus → User 단방향 | 부모 : User, 자식: ReadStatus | ReadStatus
9+
| User : Message | 1 : N | Message → User 단방향 | 부모 : User, 자식: Message | Message
10+
| User : BinaryContent | 1 : 1 | User → BinaryContent 단방향 | 부모 : User, 자식: BinaryContent | User
11+
| Channel : Message | 1 : N | Message → Channel 단방향 | 부모 : Channel, 자식: Message | Message
12+
| Channel : ReadStatus | 1 : N | ReadStatus → Channel 단방향 | 부모 : Channel, 자식: ReadStatus | ReadStatus
13+
| Message : BinaryContent | 1 : N | Message → BinaryContent 단방향 | 부모 : Message, 자식: BinaryContent | Message

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ repositories {
2525

2626
dependencies {
2727
implementation 'org.springframework.boot:spring-boot-starter-web'
28+
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2829
compileOnly 'org.projectlombok:lombok'
2930
annotationProcessor 'org.projectlombok:lombok'
3031
testImplementation 'org.springframework.boot:spring-boot-starter-test'
32+
runtimeOnly 'org.postgresql:postgresql'
33+
runtimeOnly 'com.h2database:h2'
34+
runtimeOnly 'org.springframework.boot:spring-boot-docker-compose'
3135
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
3236
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6'
3337
}

docker-compose.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
postgres-db:
3+
image: postgres:15
4+
container_name: local_postgres
5+
environment:
6+
POSTGRES_USER: discodeit_user
7+
POSTGRES_PASSWORD: discodeit1234
8+
POSTGRES_DB: discodeit
9+
ports:
10+
- "5432:5432"
11+
volumes:
12+
- db_data:/var/lib/postgresql/data
13+
14+
volumes:
15+
db_data: { }

src/main/java/com/sprint/mission/discodeit/DiscodeitApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import org.springframework.boot.SpringApplication;
88
import org.springframework.boot.autoconfigure.SpringBootApplication;
99
import org.springframework.context.ConfigurableApplicationContext;
10+
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
1011

1112
@SpringBootApplication
13+
@EnableJpaAuditing
1214
public class DiscodeitApplication {
1315

1416
public static void main(String[] args) {
Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
package com.sprint.mission.discodeit.controller;
22

3-
import com.sprint.mission.discodeit.entity.BinaryContent;
3+
import com.sprint.mission.discodeit.dto.BinaryContentDownload;
4+
import com.sprint.mission.discodeit.dto.data.BinaryContentDto;
5+
import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest;
46
import com.sprint.mission.discodeit.service.BinaryContentService;
7+
import com.sprint.mission.discodeit.storage.LocalBinaryContentStorage;
58
import com.sprint.mission.discodeit.util.LogMapUtil;
69
import io.swagger.v3.oas.annotations.tags.Tag;
10+
import java.io.IOException;
711
import lombok.RequiredArgsConstructor;
812
import org.slf4j.Logger;
913
import org.slf4j.LoggerFactory;
14+
import org.springframework.core.io.Resource;
15+
import org.springframework.http.HttpHeaders;
16+
import org.springframework.http.HttpStatus;
17+
import org.springframework.http.MediaType;
1018
import org.springframework.http.ResponseEntity;
1119
import org.springframework.web.bind.annotation.*;
1220

1321
import java.util.List;
1422
import java.util.UUID;
23+
import org.springframework.web.multipart.MultipartFile;
1524

1625
@RestController
1726
@RequiredArgsConstructor
@@ -20,21 +29,75 @@
2029
public class BinaryContentController {
2130

2231
private final BinaryContentService binaryContentService;
32+
private final LocalBinaryContentStorage localBinaryContentStorage;
2333
private static final Logger log = LoggerFactory.getLogger(BinaryContentController.class);
2434

35+
@PostMapping
36+
public ResponseEntity<BinaryContentDto> create(@RequestBody BinaryContentCreateRequest request) {
37+
BinaryContentDto createdContent = binaryContentService.create(request);
38+
log.info("{}", LogMapUtil.of("action", "create")
39+
.add("request", request)
40+
.add("contentId", createdContent.id()));
41+
return new ResponseEntity<>(createdContent, HttpStatus.CREATED);
42+
}
43+
2544
@GetMapping("/{binaryContentId}")
26-
public ResponseEntity<BinaryContent> read(@PathVariable UUID binaryContentId) {
27-
BinaryContent content = binaryContentService.find(binaryContentId);
45+
public ResponseEntity<BinaryContentDto> read(@PathVariable UUID binaryContentId) {
46+
BinaryContentDto content = binaryContentService.findById(binaryContentId);
2847
log.info("{}", LogMapUtil.of("action", "read")
2948
.add("content", content));
3049
return ResponseEntity.ok(content);
3150
}
3251

3352
@GetMapping
34-
public ResponseEntity<List<BinaryContent>> readAll(@RequestParam List<UUID> binaryContentIds) {
35-
List<BinaryContent> contents = binaryContentService.findAllByKeys(binaryContentIds);
53+
public ResponseEntity<List<BinaryContentDto>> readAll(@RequestParam List<UUID> binaryContentIds) {
54+
List<BinaryContentDto> contents = binaryContentService.findAllByIds(binaryContentIds);
3655
log.info("{}", LogMapUtil.of("action", "readAll")
3756
.add("contents", contents));
3857
return ResponseEntity.ok(contents);
3958
}
59+
60+
@GetMapping("/{binaryContentId}/download") // {binaryContentId}는 경로 변수로 사용됩니다.
61+
public ResponseEntity<Resource> downloadFile(@PathVariable UUID binaryContentId) {
62+
try {
63+
// 1. 서비스 레이어에게 다운로드에 필요한 정보 (데이터 스트림, 파일명, 타입)를 요청합니다.
64+
// 서비스는 Repository에서 메타데이터를, Storage에서 실제 데이터를 가져와 BinaryContentDownload DTO로 반환합니다.
65+
BinaryContentDownload downloadData = binaryContentService.download(binaryContentId);
66+
67+
// 2. 서비스로부터 받은 정보를 바탕으로 HTTP 응답 헤더를 설정합니다.
68+
HttpHeaders headers = new HttpHeaders();
69+
// Content-Disposition 헤더 설정: 파일을 다운로드하도록 지정하고 파일명을 명시합니다.
70+
// 파일명에 특수 문자가 포함될 경우 인코딩 처리가 필요할 수 있습니다 (여기서는 단순화).
71+
headers.add(HttpHeaders.CONTENT_DISPOSITION,
72+
"attachment; filename=\"" + downloadData.filename() + "\"");
73+
// Content-Type 헤더 설정: 파일의 MIME 타입을 명시합니다.
74+
// headers.add(HttpHeaders.CONTENT_TYPE, downloadData.getContentType()); // 아래 contentType()으로 설정 가능
75+
76+
// 3. ResponseEntity 객체를 구성하여 반환합니다.
77+
return ResponseEntity.ok() // HTTP 상태 코드 200 OK
78+
.headers(headers) // 설정한 헤더 추가
79+
// 서비스에서 제공된 컨텐츠 타입을 사용하여 응답의 Content-Type 헤더를 설정합니다.
80+
.contentType(MediaType.parseMediaType(downloadData.contentType()))
81+
// 서비스에서 제공된 InputStreamResource (파일 데이터)를 응답 본문에 설정합니다.
82+
.body(downloadData.getResource()); // BinaryContentDownload에서 제공하는 Resource 객체 사용
83+
84+
} catch (IllegalArgumentException e) {
85+
// BinaryContent 메타데이터를 서비스에서 찾을 수 없는 경우 (서비스에서 throw)
86+
// logger.warn("Download failed: Metadata not found for id: " + binaryContentId, e); // 로깅 고려
87+
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); // HTTP 상태 코드 404 Not Found 응답
88+
} catch (IOException e) {
89+
// 스토리지에서 데이터 로딩 중 I/O 오류 발생 또는 데이터가 없는 경우 (서비스에서 throw)
90+
// 서비스에서 데이터 부재와 다른 I/O 오류를 구분하여 던진다면 여기서 더 세분화된 응답 가능 (예: 데이터 부재 시 404)
91+
// 현재는 모든 I/O 오류를 500으로 처리하거나, 데이터 부재도 포함하여 404로 처리할 수 있습니다.
92+
// logger.error("Download failed: Storage error for id: " + binaryContentId, e); // 로깅 고려
93+
// 여기서는 I/O 오류 전반을 Internal Server Error로 처리합니다.
94+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
95+
.body(null); // HTTP 상태 코드 500 Internal Server Error 응답
96+
} catch (Exception e) {
97+
// 그 외 예상치 못한 오류 발생 시
98+
// logger.error("Unexpected error during download for id: " + binaryContentId, e); // 로깅 고려
99+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
100+
.body(null); // HTTP 상태 코드 500 Internal Server Error 응답
101+
}
102+
}
40103
}

src/main/java/com/sprint/mission/discodeit/controller/ChannelController.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,29 @@ public class ChannelController {
2828
private static final Logger log = LoggerFactory.getLogger(ChannelController.class);
2929

3030
@PostMapping("/public")
31-
public ResponseEntity<Channel> create(
31+
public ResponseEntity<ChannelDto> create(
3232
@RequestBody PublicChannelCreateRequest request) {
33-
Channel publicChannel = channelService.create(request);
33+
ChannelDto publicChannel = channelService.create(request);
3434
log.info("{}", LogMapUtil.of("action", "createPublic")
3535
.add("publicChannel", publicChannel));
3636

3737
return ResponseEntity.status(HttpStatus.CREATED).body(publicChannel);
3838
}
3939

4040
@PostMapping("/private")
41-
public ResponseEntity<Channel> create(
41+
public ResponseEntity<ChannelDto> create(
4242
@RequestBody PrivateChannelCreateRequest request) {
43-
Channel privateChannel = channelService.create(request);
43+
ChannelDto privateChannel = channelService.create(request);
4444
log.info("{}", LogMapUtil.of("action", "createPrivate")
4545
.add("privateChannel", privateChannel));
4646

4747
return ResponseEntity.status(HttpStatus.CREATED).body(privateChannel);
4848
}
4949

5050
@PutMapping("/{channelId}")
51-
public ResponseEntity<Channel> update(@PathVariable UUID channelId,
51+
public ResponseEntity<ChannelDto> update(@PathVariable UUID channelId,
5252
@RequestBody PublicChannelUpdateRequest request) {
53-
Channel updated = channelService.update(channelId, request);
53+
ChannelDto updated = channelService.update(channelId, request);
5454
log.info("{}", LogMapUtil.of("action", "updatePublic")
5555
.add("updated", updated));
5656

@@ -68,7 +68,7 @@ public ResponseEntity<Channel> delete(@PathVariable UUID channelId) {
6868

6969
@GetMapping
7070
public ResponseEntity<List<ChannelDto>> readAll(@RequestParam UUID userId) {
71-
List<ChannelDto> channelDtoList = channelService.readAllByUserKey(userId);
71+
List<ChannelDto> channelDtoList = channelService.readAllByUserId(userId);
7272
log.info("{}", LogMapUtil.of("action", "readAll")
7373
.add("channelDtoList", channelDtoList));
7474

0 commit comments

Comments
 (0)