π λ¬Έμ μν©
κ²μκΈμ 첨λΆλ νμΌ λ€μ΄λ‘λ μ λ€μκ³Ό κ°μ μ€λ₯κ° λ°μ:
ClassCastException: org.springframework.core.io.UrlResource cannot be cast to com.office.app.dto.PostAttachmentDownloadDTO
π λ°μ μμΉ:
- Endpoint:
GET /api/posts/{postId}/attachments/{fileId}/download
- μν©: κ²μκΈμ 첨λΆλ νμΌ λ€μ΄λ‘λ μλ μ€ μ€λ₯ λ°μ
π μμΈ λΆμ
1οΈβ£ Service κ³μΈ΅μμ Resource νμ
μ μ§μ λ°ννλ €λ€ νμ
μΊμ€ν
λ¬Έμ λ°μ
2οΈβ£ νμΌ λ©νλ°μ΄ν°(Content-Type, νμΌλͺ
λ±) λλ½
3οΈβ£ Controllerμ Service κ° λ°ν νμ
λΆμΌμΉ
β
ν΄κ²° λ°©λ²
ποΈ 1. PostAttachmentDownloadDTO μμ±
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PostAttachmentDownloadDTO {
private Resource resource;
private String contentType;
private String originalFileName;
}
π οΈ 2. Service λ©μλ μμ
public PostAttachmentDownloadDTO downloadAttachment(Long postId, Long fileId, String employeeId) {
PostAttachment attachment = postAttachmentRepository.findByIdAndPostId(fileId, postId)
.orElseThrow(() -> new FileNotFoundException("νμΌμ μ°Ύμ μ μμ΅λλ€."));
GCSResponse gcsResponse = gcsService.downloadObject(attachment.getStoredFileName(), employeeId);
return PostAttachmentDownloadDTO.builder()
.resource(new UrlResource(new URL(gcsResponse.getDownloadUrl())))
.contentType(attachment.getContentType())
.originalFileName(attachment.getOriginalFileName())
.build();
}
π 3. Controller μλ΅ μ²λ¦¬ κ°μ
@GetMapping("/{postId}/attachments/{fileId}/download")
public ResponseEntity<Resource> downloadAttachment(
@PathVariable Long postId,
@PathVariable Long fileId,
Authentication authentication) {
PostAttachmentDownloadDTO downloadInfo =
postAttachmentService.downloadAttachment(postId, fileId, authentication.getName());
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(downloadInfo.getContentType()))
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + URLEncoder.encode(downloadInfo.getOriginalFileName(), StandardCharsets.UTF_8) + "\"")
.body(downloadInfo.getResource());
}
β¨ μ£Όμ κ°μ μ¬ν
- π― DTOλ₯Ό μ¬μ©ν΄ λ°μ΄ν° μΊ‘μν
- π Content-Type λ° Content-Disposition ν€λ μ€μ
- π νκΈ νμΌλͺ
μ²λ¦¬λ₯Ό μν
URLEncoder μ μ©
- π Service-Controller κ° μ±
μ λΆλ¦¬
π‘ κ²°κ³Ό
- β
νμΌ λ€μ΄λ‘λ κΈ°λ₯ μ μ μλ
- β
νκΈ νμΌλͺ
μ μ μ²λ¦¬
- β
λΈλΌμ°μ λ€μ΄λ‘λ λμ λ¬Έμ ν΄κ²°
π μΆκ° κ³ λ €μ¬ν
π 보μ κ°ν: νμΌ μ κ·Ό κΆν κ²μ¦
π λμ©λ νμΌ μ²λ¦¬: μ€νΈλ¦¬λ° λ°©μ κ³ λ €
π λ¬Έμ μν©
κ²μκΈμ 첨λΆλ νμΌ λ€μ΄λ‘λ μ λ€μκ³Ό κ°μ μ€λ₯κ° λ°μ:
π λ°μ μμΉ:
GET /api/posts/{postId}/attachments/{fileId}/downloadπ μμΈ λΆμ
1οΈβ£ Service κ³μΈ΅μμ
Resourceνμ μ μ§μ λ°ννλ €λ€ νμ μΊμ€ν λ¬Έμ λ°μ2οΈβ£ νμΌ λ©νλ°μ΄ν°(Content-Type, νμΌλͺ λ±) λλ½
3οΈβ£ Controllerμ Service κ° λ°ν νμ λΆμΌμΉ
β ν΄κ²° λ°©λ²
ποΈ 1. PostAttachmentDownloadDTO μμ±
π οΈ 2. Service λ©μλ μμ
π 3. Controller μλ΅ μ²λ¦¬ κ°μ
β¨ μ£Όμ κ°μ μ¬ν
URLEncoderμ μ©π‘ κ²°κ³Ό
π μΆκ° κ³ λ €μ¬ν
π 보μ κ°ν: νμΌ μ κ·Ό κΆν κ²μ¦
π λμ©λ νμΌ μ²λ¦¬: μ€νΈλ¦¬λ° λ°©μ κ³ λ €