如果图片失效或者格式已乱,建议阅读原文
在【案例】搭建 Quizzes 网站,每天赚取 30-50 美元 提到下载站项目,因为整个项目代码加上一些说明,会导致内容太多,所以准备分成几部分,这样看起来更舒服。
本文主要内容:通过 Google Drive Api 将文件上传到谷歌云盘,然后获取到文件的下载链接,用户只要点击该链接就能下载文件。
这里面坑非常多,获取下载链接时, API 版本改来改去,一些方法还不可用。特别如果代码处理不当,获取到的下载链接还不能直接被下载,需要上传者授权才能下载,这里我没注意,导致后面踩了大坑。
这里直接略过,比较简单而且以前在 通过 Google API 上传视频到 Youtube 里写的非常详细,这里基本一样,只不过开通的服务不一样而已。
上传成功后获取到下载链接,但是此链接竟然要授权才能被下载。暂时没图片,这里很难描述,就直接跳过,如果碰到就会懂我意思,直接用我代码也不会碰到这个问题。
最重要的方法,传入文件地址,获取下载链接
public static String realUploadFile(String filePath){
Preconditions.checkArgument(
!UPLOAD_FILE_PATH.startsWith("Enter ") && !DIR_FOR_DOWNLOADS.startsWith("Enter "),
"Please enter the upload file path and download directory in %s", DriveSample.class);
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorize();
drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(
APPLICATION_NAME).build();
View.header1("Starting Resumable Media Upload");
File uploadedFile = uploadFile(false,filePath);
String shareLink = uploadedFile.getWebViewLink();
System.out.println(shareLink);
String fileID = uploadedFile.getId();
insertPermission(drive,fileID);
View.header1("Success!");
return shareLink;
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
return filePath;
}
接着提供里面用到的方法函数。
读取密钥文件,验证权限 ,和前面 Youtbe Api 是类似。
private static Credential authorize() throws Exception {
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(DriveSample.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=drive "
+ "into drive-cmdline-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(DriveScopes.DRIVE_FILE)).setDataStoreFactory(dataStoreFactory)
.build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
接着是里面上传代码
File uploadedFile = uploadFile(false,filePath);
private static File uploadFile(boolean useDirectUpload,String filePath) throws IOException {
File fileMetadata = new File();
fileMetadata.setWritersCanShare(true);
java.io.File UPLOAD_FILE = new java.io.File(filePath);
fileMetadata.setName(UPLOAD_FILE.getName());
FileContent mediaContent = new FileContent("image/jpeg", UPLOAD_FILE);
Drive.Files.Create insert = drive.files().create(fileMetadata, mediaContent);
insert.setFields("webViewLink,id");
MediaHttpUploader uploader = insert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(useDirectUpload);
uploader.setProgressListener(new FileUploadProgressListener());
return insert.execute();
}
这个方法中最重要的一行是设置参数 ,这里必须要如此添加两个。因为 Google Drive API 很神奇,如果不添加请求属性,最后获取到的结果对象中不会存在该属性,也就是说拿不到对应的值。比如这里:前者是链接,这里添加后,上传成功得到的对象中才会返回分享下载链接。 后者的 id 也是类似,等下会看到。
insert.setFields("webViewLink,id");
下载链接
String shareLink = uploadedFile.getWebViewLink();
因为前面请求时设置了 link
属性,所以这里能获取到 shareLink
。
同理,也添加了 id
这里也能获取到 。需要获取到 文件id 去设置权限,设置成 所有人都能读 ,不然别人点击上面链接后会发送邮件到你邮箱,请求你授权。
当初我就搞错了,在上面获取到链接后没做下面处理,直接返回使用。结果网站有流量后,每天都能收到很多邮件,又不能取消拉黑,就只能被「烦」。
String fileID = uploadedFile.getId();
private static Permission insertPermission(Drive service, String fileId) throws Exception{
Permission newPermission = new Permission();
newPermission.setType("anyone");
newPermission.setRole("reader");
return service.permissions().create(fileId, newPermission).execute();
}
经过上面授权就行,将处理后的链接当作最终结果返回。
好的,最后如果需要 xx ,在使用此功能时,别忘记下面代码。你懂的,和 通过 Google API 上传视频到 Youtube 一样。
// System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
// System.setProperty("proxyHost", "127.0.0.1");
// System.setProperty("proxyPort", "1080");
代码上面都有。如果想看的清楚点,整个文件代码我放在服务器上,下载地址在公众号「老郭种树」后台回复 0505 获取。