본문 바로가기

공부일지

240216 (google drive api)

구글드라이브에 api를 이용해 파일 업로드 하기

구글 드라이브 개발자 사이트에 프로젝트 등록

그래들 프로젝트로 하는 것 권장, 메이븐으로 진행

		<!-- 구글 드라이브 api 디펜던시 모음 -->
		<dependency>
			<groupId>com.google.api-client</groupId>
			<artifactId>google-api-client</artifactId>
			<version>2.0.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.oauth-client</groupId>
			<artifactId>google-oauth-client-jetty</artifactId>
			<version>1.34.1</version>
		</dependency>
		<dependency>
			<groupId>com.google.apis</groupId>
			<artifactId>google-api-services-drive</artifactId>
			<version>v3-rev20220815-2.0.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.auth</groupId>
			<artifactId>google-auth-library-credentials</artifactId>
			<version>1.22.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.auth</groupId>
			<artifactId>google-auth-library-oauth2-http</artifactId>
			<version>1.22.0</version>
		</dependency>

 

 

 

0. 인증서 객체 생성하기

	private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
	private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
	private static final String TOKENS_DIRECTORY_PATH = "tokens";

	/**
	 * 여기 권한을 수정해야 파일 읽기만 할건지 쓰기말한거지 등등을 결정할 수 있고, 매번 토큰 새로 처리하는게 아니라 StoredToken이
	 * 저장되기 때문에 tokens폴더에 있는 StoredCredential를 삭제해줘야함
	 */
//    private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
	private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE);
	private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

	private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
		// Load client secrets.
		InputStream in = DriveQuickStart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
		if (in == null) {
			throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
		}
		GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

		// Build flow and trigger user authorization request.
		GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
				clientSecrets, SCOPES)
				.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
				.setAccessType("offline").build();
		LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
		Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
		// returns an authorized Credential object.
		return credential;
	}
  • CREDENTIALS_FILE_PATH 는 스프링 레거시 기준으로 src/main/resources 폴더를 기준으로 설정된다. 해당 폴더에 OAuth 2.0 클라이언트 ID를 json으로 받아서 이름 변경 후 저장해준다.
  • SCOPES 는 드라이브 저장 수정 등 다양한 기능을 모두 사용 가능하게 오픈하기 위해 DriveScopes.DRIVE로 설정했다.
  • 권한을 낮추려면 다른 스코프를 사용할 수 있다.

 

1. 구글드라이브 연결 테스트

	private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
	private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
	private static final String TOKENS_DIRECTORY_PATH = "tokens";

// Build a new authorized API client service.
		final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
		Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
				.setApplicationName(APPLICATION_NAME).build();

		// Print the names and IDs for up to 10 files.
		FileList result = service.files().list().setPageSize(1).setFields("nextPageToken, files(id, name)").execute();

		List<File> files = result.getFiles();
		if (files == null || files.isEmpty()) {
			System.out.println("No files found.");
		} else {
			System.out.println("Files:");
			for (File file : files) {
				System.out.printf("%s (%s)\\n", file.getName(), file.getId());
			}
		}
  • API 사용을 위한 service 객체를 생성한다.
  • 구글 드라이브의 파일 1개를 filelist에 result라는 이름으로 담는다.
  • 연결 성공 시 getCredentials을 통해 토큰이 생성된다.(토큰 역할은 몰?루)

 

 

2. 구글 드라이브에 파일 업로드 처리

	Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
				.setApplicationName(APPLICATION_NAME).build();		

		System.out.println("\\n\\n 파일 업로드 시작..");

		Path currentWorkingDir = Paths.get("").toAbsolutePath();
		File fileMetaData = new File();
		// 업로드 하는 파일 이름
		fileMetaData.setName("cctv.png");
		// 업로드 할 폴더 id
		fileMetaData.setParents(Collections.singletonList("1McmcIzcUSQAIpdkV0KmI6k6YMe-y1tqq"));
		// 실물 파일 경로, 혹은 multipart로 입력받은 file을 file객체로 만들어서 가져오기		
		java.io.File f = new java.io.File(currentWorkingDir + "/src/main/webapp/resources/images/prod_img/cctv.png");
		// 파일 저장경로
		FileContent fileContent = new FileContent("image/jpeg", f);
		//업로드 완료 후 데이터를 file에 담기
		File file = service.files().create(fileMetaData, fileContent).execute();
		//저장한 파일의 id 반환
		file.getId();
		
		System.out.println("\\n\\n 파일 업로드 완료");

프로젝트에 사용한 파일 업로드 메소드

public String fileUpload(MultipartFile multipartFile) throws GeneralSecurityException, IOException {
		// Build a new authorized API client service.
		final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
		Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
				.setApplicationName(APPLICATION_NAME).build();
		
		// 멀티파트 파일을 이용해 파일 객체 생성
		java.io.File f = new java.io.File(multipartFile.getOriginalFilename());
		multipartFile.transferTo(f);
		
		//구글 드라이브에서 제공하는 파일 객체 생성
		File fileMetaData = new File();
		// 업로드 하는 파일 이름
		fileMetaData.setName(multipartFile.getOriginalFilename());
		// 업로드 할 폴더 id
		fileMetaData.setParents(Collections.singletonList("1McmcIzcUSQAIpdkV0KmI6k6YMe-y1tqq"));
		// 파일 실물 정보를 담을 객체 생성
		FileContent fileContent = new FileContent("image/jpeg", f);
		// 드라이브 서비스를 이용하여 구글드라이브에 업로드 한다. File과 FileContent 객체를 같이 묶어서 전송하고, 전송 결과를 File의 형태로 반환한다.
		File file = service.files().create(fileMetaData, fileContent).execute();
		// 저장한 파일의 id 반환
		return file.getId();
	}

 

 

 

3. 구글 드라이프 파일 검색하기

		List files = new ArrayList();

		String pageToken = null;
		do {
			//setQ 내부에 검색 옵션을 넣어준다.
			// 검색 옵션 링크 <https://developers.google.com/drive/api/guides/search-files?hl=ko>
			//이름이 'hello'인 파일							name = 'hello'
			//이름에 '안녕하세요' 및 '작별'이라는 단어가 포함된 파일 	name contains 'hello' and name contains 'goodbye'
			//지정된 날짜 이후에 수정된 파일						modifiedTime > '2012-06-04T12:00:00' // default time zone is UTC

			FileList result = service.files().list().setQ("mimeType='image/png'").setSpaces("drive")
					.setFields("nextPageToken, files(id, name)").setPageToken(pageToken).execute();
			for (File file : result.getFiles()) {
				System.out.printf("Found file: %s (%s)\\n", file.getName(), file.getId());
			}

			files.addAll(result.getFiles());

			pageToken = result.getNextPageToken();
		} while (pageToken != null);
  • List<File> files에 검색 결과를 담아서 나오게 된다.

 

 

4. 구글드라이프 파일 삭제

//delete 내부에 파일 id 입력
service.files().delete("1ZUveApPBe7amWc46XMsCKCMLKLCn7oUd").execute();

 

 

 

5. 구글드라이프 파일 다운로드

		ByteArrayOutputStream byteArrayOutputStream;
		try {
			OutputStream outputStream = new ByteArrayOutputStream();

			service.files().get("1sDGp10ksdadW3dGrPrk6huhwYPy2l8OT").executeMediaAndDownloadTo(outputStream);

			byteArrayOutputStream = (ByteArrayOutputStream) outputStream;
		} catch (GoogleJsonResponseException e) {
			// TODO(developer) - handle error appropriately
			System.err.println("Unable to move file: " + e.getDetails());
			throw e;
		}
		//파일 경로는 서버 드라이브 루트부터 시작(하는듯)
		java.io.File filePath = new java.io.File("/HanulFianlB/Web/HanulFinalB/src/main/webapp/resources", "cctv.png");
		FileOutputStream fos = new FileOutputStream(filePath);
		fos.write(byteArrayOutputStream.toByteArray());
		fos.flush();
		fos.close();
  • service.files().get("1sDGp10ksdadW3dGrPrk6huhwYPy2l8OT").executeMediaAndDownloadTo(outputStream); 이 코드로 파일 정보 bytearray로 저장해둔다.
  • bytearrayoutputstream 을 배열로 바꾸고 저장한다.

 

 

6. 구글 드라이브의 이미지 파일 호스팅하기

 

“http://drive.google.com/uc?export=view&id=파일 아이디”의 URL을 기본 골자로 한다.

원래 img태그에 src요소로 사용가능했지만 구글 드라이브 제3자 쿠키 요구사항에 대한 변경의 영향으로 불가능해졌다.

 

대체방법1

<iframe src="https://drive.google.com/file/d/${fileId}/preview" 
width="640" height="480"></iframe>
  • iframe을 이용하여 파일 보여주기
  • 이미지처럼 띄워지는게 아닌 미리보기 창으로 나온다.
  • 별도의 조작 UI가 같이 출력된다.

대체방법2

<img src="https://drive.google.com/thumbnail?id=${fileId}&sz=w640" />
  • 썸네일 기능을 이용하여 img의 src에 링크를 걸어준다.

'공부일지' 카테고리의 다른 글

240115 (IoT)  (0) 2024.01.15
231227 (Spring)  (0) 2023.12.27
231221 (Spring)  (0) 2023.12.21
231220 (Spring)  (0) 2023.12.20
231219 (Android)  (0) 2023.12.20