현재 이미지와 이미지에 대한 정보를 담고 있는 객체를 서버로 전송하면,
이미지의 메타데이터를 추출하여 이미지에 대한 정보를 담고 있는 객체에 합쳐서 db에 저장하고
이미지는 s3에 저장하는 꽤나 복잡한 일을 해야 한다.

그림으로 보면 이런 느낌이다.
클라이언트에서 이미지와 분실장소 등에 대한 세부 정보를 서버로 보낸다.
서버는 이미지에서 메타데이터를 추출하여 db에 저장, 이미지는 s3에 저장한다.
현재 플러터에서 이미지를 보내본 적도 없고, 스프링에서 이미지를 받아본 적도 없기 때문에 먼저 이미지를 보내고 s3에 저장하는 과정을 구현해보려 한다.
1. 이미지 선택
ElevatedButton(
onPressed: () => _pickImage(),
child: Container()
기본적으로 setState를 활용하여 이미지 선택 유무를 판단할 것이기 때문에 Stateful 위젯을 사용했고 버튼을 누르면 _pickImage 메서드가 실행된다.
File? _imageFile;
Future<void> _pickImage() async {
final pickedImageFile =
await ImagePicker().pickImage(source: ImageSource.gallery);
setState(() {
_imageFile = File(pickedImageFile!.path);
});
}
이미지를 선택하기 위해 ImagePicker 라이브러리를 사용하였는데,
ImagePicker().pickImage(source: ImageSource.gallery)를 통해 갤러리에서 이미지 선택을 가능하도록 한다.
이후, 선택된 파일은 pickedImageFile에 저장되고 파일의 경로로 새로운 File을 생성해 _imageFile에 저장한다.
2. 이미지 전송
Future<void> _sendImage() async {
if (_image == null) return;
FormData formData = FormData.fromMap({
"image":
await MultipartFile.fromFile(_image!.path, filename: 'myImage.jpg')
});
Dio dio = Dio();
await dio.post("$serverIp/reportItem", data: formData);
}
이미지 전송에는 dio 라이브러리를 사용했는데, 기존에 사용하던 http 라이브러리는 formData를 지원하지 않는다고 하여 좀 더 성능이 좋다는 dio 라이브러리를 사용해 보게 되었다.
MultipartFile.fromFile(_image!.path, filename: 'myImage.jpg')을 통해 이미지와 이미지 이름을 formData 변수에 포함시킬 수 있다.
dio.post를 통해 첫 번째 인자로는 url, 두 번째 인자로 formData를 포함하여 서버로 전송하였다.
3. 서버에서 이미지 받기(Spring)
@PostMapping("/url")
public ResponseEntity<?> uploadImage(@Valid @RequestPart("image") MultipartFile imageDto) {
}
먼저 플러터에서 서버로 전송하는 url의 응답 메서드를 정의해 보았다.
@RequestPart("image") MultipartFile imageDto 이 구문은 요청 본문의 image라는 키에 해당하는 파트를 MultipartFile 타입으로 받아서 imageDto 파라미터에 저장하는 것으로,
이후 imageDto를 통해 이미지의 메타데이터와 s3에 저장할 수 있도록 하였다.
이후,
s3Service.uploadImageToS3(imageDto);
스프링의 mvc 패턴을 적용하기 위해 분리된 s3 서비스 로직을 호출하였다.
4. s3로 이미지 저장
public void uploadImageToS3(MultipartFile image) { //이미지를 S3에 업로드
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("image/"+ext);
try {
PutObjectResult putObjectResult = amazonS3.putObject(new PutObjectRequest(
bucketName, newName, image.getInputStream(), metadata
).withCannedAcl(CannedAccessControlList.PublicRead));
} catch (IOException e) {
// 예외 처리
}
}
필요한 구문만 넣었는데, 먼저 s3에 같이 저장할 메타데이터를 위해 ObjectMetadata라는 metadata 객체를 만들어 이미지의 확장자를 삽입했다.
이후, amazonS3.putObject 메서드를 사용해 버킷에 새로운 이미지의 이름과 이미지, 메타데이터를 전송하여 저장하였다.
5. 결과

이렇게 하여 성공적으로 플러터에서 이미지를 전송하여 s3에 저장해 보았다!
'앱 > flutter' 카테고리의 다른 글
| [flutter] 플러터 로컬 서버 api 오류 해결방법 (1) | 2025.03.23 |
|---|