본문 바로가기

Project 기록/식당예약웹

네이버클라우드 s3 스토리지 Spring 프로젝트에서 사용하기 (NCP, Spring, 이미지) ②

728x90
반응형

 

https://coding-hwije.tistory.com/72

 

요기까지 진행이 되어 있어야한다. NCP에서 s3 스토리지를 만들었다.

 

스프링코드 구현

 

난 maven을 사용했기때문에 다음과 같이 의존성을 추가해 줬다. 

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
    <version>1.11.238</version>
</dependency>

 

내가 구글링했을때 build.gradle 은 이거해주면 된다고 하긴한다.

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

 

 

application.properties 에 다음과 같이 적어줬다.

s3 브라우저에 입력했던 accesskey와 secretkey 써준다.

spring.s3.accessKey=54CB@#$@#$비밀@$@#2@$#B
spring.s3.secretKey=E5BD6!$#@$@#$@비밀@$@@#$@#$7FE8
spring.s3.bucket=dsilbucket

file.upload-dir=/path/to/upload/directory

 

 

NcpConfig 파일을 만들어 줬다.

 

@Configuration
public class NcpConfig {
    private final String endPoint = "https://kr.object.ncloudstorage.com";
    private final String regionName = "kr-standard";

    @Value("${spring.s3.accessKey}")
    private String accessKey;

    @Value("${spring.s3.secretKey}")
    private String secretKey;

    @Value("${spring.s3.bucket}")
    private String bucketName;

    @Bean
    public AmazonS3Client amazonS3Client() {
        BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
        return (AmazonS3Client) AmazonS3ClientBuilder
                .standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, regionName))
                .withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials))
                .build();
    }
}

 

 

FileDTO 를 만들어 줬다. 파일 이름, 경로, url 을 갖고 있다.

@Getter
@Setter
@ToString
@Builder
public class FileDTO {

    private String originalFileName;
    private String uploadFileName;
    private String uploadFilePath;
    private String uploadFileUrl;

}

 

 

Service 클래스를 만들어 줬다. 

 

FileService.class

 

난 uploadFiles 메소드를 사용했다. MulitpartFile 타입의 리스트와, filePath(디렉토리명) 을 파라미터로 받으면 filePath 경로에 이미지가 저장된다.

url이 생성되는데, 중간에 uploadFileUrl 변수에 이미지 url이 저장된다. 

 

@Service
@RequiredArgsConstructor
@Transactional
public class FileService {

    private final AmazonS3Client amazonS3Client;
    private final ReviewRepository reviewRepository;

    @Value("${spring.s3.bucket}")
    private String bucketName;

    @Value("${file.upload-dir}")
    private String uploadDir;

    public String getUuidFileName(String fileName) {
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        return UUID.randomUUID().toString() + "." + ext;
    }

    public List<FileDTO> uploadFilesSample(List<MultipartFile> multipartFiles) {
        return uploadFiles(multipartFiles, "sample-folder");
    }
// 리뷰등록
    public List<FileDTO> uploadFilesReview(List<MultipartFile> multipartFiles) {
        return uploadFiles(multipartFiles, "sample-folder");
    }

    public List<FileDTO> uploadFiles(List<MultipartFile> multipartFiles, String filePath) {
        List<FileDTO> s3files = new ArrayList<>();

        for (MultipartFile multipartFile : multipartFiles) {
            String originalFileName = multipartFile.getOriginalFilename();
            String uploadFileName = getUuidFileName(originalFileName);
            String uploadFileUrl = "";

            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(multipartFile.getSize());
            objectMetadata.setContentType(multipartFile.getContentType());

            try (InputStream inputStream = multipartFile.getInputStream()) {
                String keyName = filePath + "/" + uploadFileName;

                amazonS3Client.putObject(
                        new PutObjectRequest(bucketName, keyName, inputStream, objectMetadata)
                                .withCannedAcl(CannedAccessControlList.PublicRead));

                uploadFileUrl = amazonS3Client.getUrl(bucketName, keyName).toString(); // S3에서 파일 URL을 가져옴
                System.out.println(uploadFileUrl+" 히얼~~~ ");

            } catch (IOException e) {
                e.printStackTrace();
            }

            s3files.add(
                    FileDTO.builder()
                            .originalFileName(originalFileName)
                            .uploadFileName(uploadFileName)
                            .uploadFilePath(filePath)
                            .uploadFileUrl(uploadFileUrl)
                            .build());
        }

        return s3files;
    }
}

 

 

내가 사용하는 컨트롤러를 보자.

난 식당 리뷰등록할 때 사진을 업로드할 수 있게 해놓았다. 

 

 

요거긴한데 ...  주석으로 ***** 친 곳 보면 될 것 같다.

 

이미지를 받는 파라미터의 데이터 타입을 MultipartFile 로 했다. 

MultipartFile은 Spring Framework에서 파일 업로드를 처리하는 데 사용되는 인터페이스다. 이를 통해 HTTP 요청에서 전송된 파일을 쉽게 다룰 수 있다.

 

'file' 에 업로드한 내용을 변수로 받았다. 

public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file, //

 

"reviews"라는 경로에 s3 스토리지에 저장할 거다 .

fileDTOList 에 fileDTO 들을 받았다. 그 후 String img 에다가 getUploadFileUrl()로 이미지 url을 담았다.

List<FileDTO> fileDTOList = fileService.uploadFiles(List.of(file), "reviews");
        String img = fileDTOList.get(0).getUploadFileUrl();

 

 

풀 코드:

@PostMapping("/registerReview")
public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file, //******
                                    @RequestParam("reviewContents") String reviewContents,
                                    @RequestParam("reservationId") Long reservationId,
                                    @RequestParam("registerDate") String registerDate,
                                    @RequestParam("reviewScore") Long reviewScore,
                                    @RequestParam("userEmail") String userEmail) {
    try {
        // *******
        List<FileDTO> fileDTOList = fileService.uploadFiles(List.of(file), "reviews");
        String img = fileDTOList.get(0).getUploadFileUrl();

        // Save review details
        ReviewRequest reviewRequest = ReviewRequest.builder()
                .reviewContents(reviewContents)
                .reservationId(reservationId)
                .registerDate(LocalDate.parse(registerDate))
                .reviewScore(reviewScore)
                .userEmail(userEmail)
                .img(img)
                .build();

        myDiningService.registerReview(reviewRequest);

        return ResponseEntity.ok("File uploaded and review saved successfully");
    } catch (Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred: " + e.getMessage());
    }
}

 

참고로 저 url 을 크롬브라우저에 치면 바로나온다. 

 

 

 

저 String 인 url 을 디비에 저장해서 사용했다.

 

프론트에서 저 값 불러와서 출력시켜서 사용하자, 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형