포스트

Day84 실습프로젝트(NCP)

SQL 설정하기

1. NCP에서 sql server생성하기

  • NCP에서 Sql을 생성하고 Public 도메인을 생성한다.

2. MySQL생성 하기

  • 터미널에서 mysql -h 호스트주소 -u 유저정보를 통해 기본 DB를 설정한다.

3. Spring에 불러오기

  • AppConfig.java에서 @PropertySource("classpath:config/jdvc.properties")를 설정한다.
  • 데이터소스를 설정한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    @Bean
    public DataSource dataSource(
            @Value("${jdbc.driver}") String jdbcDriver,
            @Value("${jdbc.url}") String jdbcUrl,
            @Value("${jdbc.username}") String jdbcUsername,
            @Value("${jdbc.password}") String jdbcPassword) {
      DriverManagerDataSource ds = new DriverManagerDataSource();
      ds.setDriverClassName(jdbcDriver);
      ds.setUrl(jdbcUrl);
      ds.setUsername(jdbcUsername);
      ds.setPassword(jdbcPassword);
      return ds;
    }
    

Storage Object 설정하기

1. 라이브러리 생성 및 기본 설정

1) 라이브러리 생성

  • ncp의 Starage Object는 aws의 s3라이브러리를 사용한다.

    1
    2
    3
    
      // build.gradle
      // https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3
      implementation 'com.amazonaws:aws-java-sdk-s3:1.12.772'
    

2) bucket 생성

  • bucket 정보를 담은 properties를 생성한다.

    1
    2
    3
    4
    5
    6
    
      #NCP Cloud Service
      ncp.storage.endpoint=https://kr.object.ncloudstorage.com
      ncp.storage.regionname=kr-standard
      ncp.storage.bucketname=bitcamp-bucket96
      ncp.accesskey=acceskey
      ncp.secretkey=secretkey
    
  • Spring MVC에서 propertySource를 설정한다.

    1
    2
    3
    4
    
      @PropertySource("file:${user.home}/config/ncp.properties")
      public class AppConfig{
        //생략
      }
    

3) Service 인터페이스 및 구현체 생성

  • service 인터페이스를 구현한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      public interface StorageService {
      String CONTENT_TYPE = "contentType";
        
      void upload(String filePath, InputStream in, Map<String, Object> options) throws Exception;
        
      void delete(String filePath) throws Exception;
        
      void download(String filePath, OutputStream out) throws Exception;
      }
    
  • service 구현체를 생성한다.
  • @Service를 어노테이션을 생성하면 Spring MVC에서 인터페이스에 대한 구현체를 자동으로 생성한다.
  • 단, 하나의 구현체의 여러개의 Service를 사용하려면 @Primary를 지정하거나 구현체Service("name")과 컨트롤러에 Qualifier("name")을 설정 해야한다.
  • 구현체의 생성자에서는 AppConfig에서 저장된 file Value값을 꺼내와야한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
      @Service
      @Service
      public class NcpObjectStorageService implements StorageService {
        
        private AmazonS3 s3;
        
        @Value("${ncp.storage.bucketname}")
        private String bucketName;
        
        public NcpObjectStorageService(@Value("${ncp.storage.endpoint}") String endPoint,
            @Value("${ncp.storage.regionname}") String regionName,
            @Value("${ncp.accesskey}") String accessKey,
            @Value("${ncp.secretkey}") String secretKey) {
          this.s3 = AmazonS3ClientBuilder.standard()
              .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, regionName))
              .withCredentials(
                  new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
              .build();
        }
        
        @Override
        public void upload(String filePath, InputStream in, Map<String, Object> options)
            throws Exception {
        }
          
        @Override
        public void delete(String filePath) throws Exception {
        }
        
        @Override
        public void download(String filePath, OutputStream out) throws Exception {
        }
      }
    

2. upload

1) NCP 가이드

  • ncp API에 따라 ncp서버에 요청을 보내야 파일시스템을 사용할 수 있다.
  • 파일을 클라우드에 업로드 하기 위해서는 버켓, 폴더, 인풋스트림이 필요하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
      ObjectMetadata objectMetadata = new ObjectMetadata();
      objectMetadata.setContentLength(0L);
      objectMetadata.setContentType("application/x-directory");
      PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, folderName, new ByteArrayInputStream(new byte[0]), objectMetadata);
        
      try {
          s3.putObject(putObjectRequest);
          System.out.format("Folder %s has been created.\n", folderName);
      } catch (AmazonS3Exception e) {
          e.printStackTrace();
      } catch(SdkClientException e) {
          e.printStackTrace();
      }
    

2) myapp적용하기

  • 클라이언트가 Multipart/form-data 형태로 Post요청을 보내면 서버측에서 MultipartFile[]로 받는다.
  • File의 UUID와 Filename을 AttachFile 객체에 저장한다.
  • 기타 부가 정보를 Map객체에 담고 StorageService.upload를 호출한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
      upload(String filePath, InputStream in, Map<String, Object> options){
        // 메타데이터 생성 (메타데이터 : 데이터를 설명하는 데이터)
        ObjectMetadata = objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType((String) options.get(COTENT_TYPE));
          
        // 파일 요청 정보 생성
        PutObjectRequest putObjectRequest =
            new PutObjectRequest(bucketName, filePath, in, objectMetadata).
                withCannedAcl(CannedAccessControlList.PublicRead);
          
        // 파일 업로드 
        s3.putObject(putObjectRequest);
      }
    

    3) update

  • Controller의 update의 파일 적용 부분도 동일하게 적용한다.

2. delete

1) NCP 가이드

  • 파일경로와 버켓 정보만 있으면 삭제 할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      // delete object
      try {
          s3.deleteObject(bucketName, objectName);
          System.out.format("Object %s has been deleted.\n", objectName);
      } catch (AmazonS3Exception e) {
          e.printStackTrace();
      } catch(SdkClientException e) {
          e.printStackTrace();
      }
    

2) 파일 삭제

  • StorageService.delete는 파일경로와 버켓 정보만 있으면 삭제 할 수 있다.
  • Controller.deleteController.fileDelete에 적용한다.

    1
    
      s3.deleteObject(bucketName, filePath);
    

3. download

1) NCP가이드

  • 로컬파일 시스템에서 출력할 outputStream이 필요하다.
  • 클라우드에서 보낸 파일을 InputStream을 읽으면 outputStream에 담는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
try {
    S3Object s3Object = s3.getObject(bucketName, objectName);
    S3ObjectInputStream s3ObjectInputStream = s3Object.getObjectContent();

    OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(downloadFilePath));
    byte[] bytesArray = new byte[4096];
    int bytesRead = -1;
    while ((bytesRead = s3ObjectInputStream.read(bytesArray)) != -1) {
        outputStream.write(bytesArray, 0, bytesRead);
    }

    outputStream.close();
    s3ObjectInputStream.close();
    System.out.format("Object %s has been downloaded.\n", objectName);
} catch (AmazonS3Exception e) {
    e.printStackTrace();
} catch(SdkClientException e) {
    e.printStackTrace();
}

2) myapp에 적용하기

  • s3객체에서 버켓과 파일 패쓰에 대한 정보를 얻는다.
  • s3객체의 inputStream을 준비한다.
  • 준비한 OutputStream에 담는다.
1
2
3
4
5
6
7
8
9
10
S3Object s3Object = s3.getObject(bucketName, filePath);
    S3ObjectInputStream s3ObjectInputStream = s3Object.getObjectContent();

    byte[] buf = new byte[4096];
    int len = -1;
    while ((len = s3ObjectInputStream.read(buf)) != -1) {
      out.write(buf, 0, len);
    }

    s3ObjectInputStream.close();
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.