这两天想给博客做个插件,利用阿里云的OSS来存储文件.但阿里的文档和代码都烂的超乎想象,要么代码老旧不堪,要么跟小脚老太一样引入一坨依赖,想必这块是外包团队做的吧,或者阿里非核心业务员的技术水平也就这样吧.
所以想绕开阿里云官方提供的代码自己整一套OSS的API,先跑一个上传文件的demo,能在客户端跑通后再用代码去实现.最简单的方法就是用REST client来模拟.折腾了一下,还挺费劲,记录下折腾过程
先来试试上传文件,选择PUT方法,要请求的URL为http://baicaidoc.oss-cn-shenzhen.aliyuncs.com/image/small/mm1.jpg ,添加以下header,header头需要包含哪些内容可以看这里
Authorization:OSS
LTAIxkX6Qj2OuMZ6:tLZ7nYYP/hkCJbG/6gkOJ7Mi4E=
Date:Thu, 25 Jan 2018 15:20:39 GMT
Content-Disposition:attachment;filename=ivy.jpg
Host:baicaidoc.oss-cn-shenzhen.aliyuncs.com
Content-Encoding:utf-8
然后在body里添加file body. 至于header头怎么写和Authorization字段计算的方法,文档里说的比较清晰了https://help.aliyun.com/document_detail/31951.html. 尤其需要注意的是Date必须是GMT格式,这个对Java来说也好办,不过要注意时区的问题,GMT时间比东八区慢了8个小时.还有Host需要带上bucket,这在早期是不需要的(早期带上反而会报错SignatureDoesNotMatch) 另外就是这个Authorization字段的签名需要注意,base64需要处理byte[]数组,而不是字符串.所以用网上的在线验证工具是验证不了的. Java版的签名代码如下:
import bai.tool.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* Hello world!
*
*/
public class App
{
public static byte[] hamcsha1(byte[] data, byte[] key)
{
try {
SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
return mac.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
public static void main( String[] args ) {
String toSign="PUT\n" +
"\n" +
"image/jpeg; charset=UTF-8\n" +
"Thu, 25 Jan 2018 15:20:39 GMT\n" +
"/baicaidoc/image/small/mm1.jpg";
String accessKey="OrzrzxIsfpFjA7S7yk0Lwy8Bw21TLhquhboiip56";
byte[] hm=hamcsha1(toSign.getBytes(),accessKey.getBytes());
System.out.println("OSS LTAIxkX6Qj2OuMZ6:"+Base64.encodeToString(hm));
}
}
客户端能跑通就好办了,最后是代码,使用HttpURLConnection来实现PUT上传代码。阿里云的OSS SDK太重了,而一般常用的就上传和删除功能
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class OSSUpload {
public String httpUrlConnectionPut(String fileName) {
String result = "";
URL url = null;
String httpUrl = "http://baicaidoc.oss-cn-shenzhen.aliyuncs.com/image/small/test.jpg";
try {
url = new URL(httpUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (url != null) {
HttpURLConnection urlConn;
try {
urlConn = (HttpURLConnection) url.openConnection();
File file = new File(fileName);
urlConn.setRequestProperty("content-type", "image/jpeg; charset=UTF-8");
urlConn.setDoOutput(true);// http正文内,因此需要设为true, 默认情况下是false;
urlConn.setDoInput(true);// 设置是否从httpUrlConnection读入,默认情况下是true;
urlConn.setConnectTimeout(15 * 1000);
urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36");
//设置请求方式为 PUT
urlConn.setRequestMethod("PUT"); urlConn.setRequestProperty("Connection", "Keep-Alive");
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
urlConn.setRequestProperty("Host", "baicaidoc.oss-cn-shenzhen.aliyuncs.com");
urlConn.setRequestProperty("Content-Encoding", "UTF-8");
urlConn.setRequestProperty("Date", sdf.format(new Date()));
urlConn.setRequestProperty("Content-Length", String.valueOf(file.length()));
urlConn.setRequestProperty("Authorization", "OSS LTAIxk223j2OuMZ6:tLZ74YYP/hkCJbG/6gkOJ7Mi4E=");
DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
//写入请求参数
try {
InputStream in = new FileInputStream(file);
int bytes = 0;
byte[] bufferOut = new byte[4096];
while ((bytes = in.read(bufferOut)) != -1) {
dos.write(bufferOut, 0, bytes);
}
dos.flush();
dos.close();
InputStream is = urlConn.getInputStream();
int ch;
StringBuffer b = new StringBuffer();
while ((ch = is.read()) != -1) {
b.append((char) ch);
}
System.out.println("result:" + b.toString());
}catch (IOException e){
e.printStackTrace();
InputStream is=urlConn.getErrorStream();
int ch;
StringBuffer b = new StringBuffer();
while ((ch = is.read()) != -1) {
b.append((char) ch);
}
System.out.println("error result:"+b.toString());
}
urlConn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}finally {
}
}
return result;
}
public static void main(String[] args) {
OSSUpload oss = new OSSUpload(); oss.httpUrlConnectionPut("/home/chen/Desktop/tmp/sd.png");
}
}