주뇽's 저장소
[Troubleshooting] Spring Boot와 S3, Flutter를 사용하여 이미지 업로드 시 발생한 문제 해결하기 본문
웹개발/SpringBoot
[Troubleshooting] Spring Boot와 S3, Flutter를 사용하여 이미지 업로드 시 발생한 문제 해결하기
뎁쭌 2024. 5. 20. 23:51728x90
반응형
내용:
최근에 Spring Boot와 S3, Flutter를 사용하여 게시판 프로젝트를 진행하던 중, 게시글에 이미지를 함께 올리는 기능을 구현하면서 여러 가지 문제에 직면했다. 이 글에서는 해당 문제의 원인과 해결 방법에 대해 자세히 설명한다.
문제 상황:
- Spring Boot와 JPA를 사용하여 게시판 프로젝트를 진행 중이었다.
- 게시글에 이미지를 함께 업로드하는 기능을 구현하려고 했다.
- Postman을 사용하여 API를 테스트하던 중
Content-Type 'multipart/form-data'
와 관련된 여러 오류가 발생했다. - 특히,
Content-Type 'application/octet-stream' is not supported
라는 오류가 반복적으로 발생했다.
문제 원인:
- Spring Boot에서
multipart/form-data
로 전송된 데이터를 올바르게 처리하지 못하고 있었다. - Postman에서 요청을 보내는 과정에서
Content-Type
이 올바르게 설정되지 않아 발생한 문제였다. - 또한, S3에 이미지를 업로드할 때 메타데이터 설정이 누락되어 있었고, 이로 인해 발생한 경고 메시지들도 있었다.
해결 방법 1: Controller에서 @RequestPart 어노테이션 사용
먼저, 컨트롤러에서 @RequestPart
어노테이션을 사용하여 JSON 데이터를 처리하고, 이를 객체로 변환한다.
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.bind.annotation.RequestPart;
@PostMapping("/{categoryId}/post")
public ResponseEntity<String> createPost(@PathVariable(name = "categoryId") Long categoryId,
@RequestPart(value = "images", required = false) List<MultipartFile> files,
@RequestPart("postRequest") String postRequestJson,
@AuthenticationPrincipal CustomUserDetails userDetails) {
if (categoryId != 1) {
ObjectMapper objectMapper = new ObjectMapper();
PostRequest postRequest;
try {
postRequest = objectMapper.readValue(postRequestJson, PostRequest.class);
} catch (JsonProcessingException e) {
return ResponseEntity.badRequest().body("Invalid JSON format");
}
UserAccount userAccount = userDetails.getUserAccount();
return postService.save(postRequest, userAccount, categoryId, files);
}
return ResponseEntity.badRequest().body("인기 게시판에는 게시글 작성이 불가능합니다.");
}
해결 방법 2: S3Service에서 ObjectMetadata 설정
이미지를 S3에 업로드할 때 ObjectMetadata
에 Content-Length와 Content-Type을 설정한다.
import com.amazonaws.services.s3.model.ObjectMetadata;
private String uploadImage(MultipartFile file, String s3Key) {
try {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize()); // Content-Length 설정
metadata.setContentType(file.getContentType()); // Content-Type 설정
amazonS3.putObject(new PutObjectRequest(bucket, s3Key, file.getInputStream(), metadata));
} catch (IOException e) {
throw new RuntimeException("Failed to upload image to S3", e);
}
return amazonS3.getUrl(bucket, s3Key).toString();
}
추가 고려사항:
캐시로 인한 데이터 불일치 문제를 해결할 때와 마찬가지로, 다음 사항들을 고려할 수 있다.
캐시 설정 조정:
spring.jpa.properties.hibernate.cache.use_second_level_cache
속성을false
로 설정하여 2차 캐시를 비활성화할 수 있다.spring.jpa.properties.hibernate.cache.use_query_cache
속성을false
로 설정하여 쿼리 캐시를 비활성화할 수 있다.
캐시 무효화:
- 데이터 변경 작업이 발생한 경우, 해당 데이터와 관련된 캐시를 명시적으로 무효화할 수 있다.
@CacheEvict
어노테이션을 사용하여 특정 캐시 엔트리를 제거할 수 있다.
캐시 범위 제한:
@Cacheable
어노테이션의condition
속성을 사용하여 캐시 적용 조건을 지정할 수 있다.- 특정 조건에 해당하는 경우에만 캐시를 사용하도록 제한할 수 있다.
마무리:
Spring Boot와 S3, Flutter를 사용하여 이미지 업로드 시 발생한 문제를 해결하는 방법에 대해 알아보았다. @RequestPart
어노테이션을 사용하여 JSON 데이터를 처리하거나, S3에 이미지를 업로드할 때 메타데이터를 설정하는 것이 효과적인 해결책이 될 수 있다. 추가로 캐시 설정 조정, 캐시 무효화, 캐시 범위 제한 등의 방법을 고려하여 캐시 관련 문제를 해결할 수 있다.