您的位置:首页 > 其它

关于阿里云OSS上传以及下载的处理方法

2017-06-22 17:48 381 查看
正好这个项目快结束了 ,被阿里云下载折腾了好久,网上相关支持又比较少,所有我结合自己的项目,简单的讲一下。
1.OSSObjectUtils基于OSS官方文档写的工具类


public class OSSObjectUtils {

private static Logger logger = LoggerFactory.getLogger(OSSObjectUtils.class);

private static OSSClient ossClient = new OSSClient(OSSConfig.ENDPOINT_SHANGHAI, OSSConfig.ACCESSKEY_ID, OSSConfig.ACCESSKEY_SECRET);
//private static OSSClient ossClient = new OSSClient("http://oss-cn-shanghai.aliyuncs.com", "0aHuVNGwxXsHDRIg", "6dvOMka7ON0DogefcWm09MbR4ofymB");

private static String ENDPOINTINFO = ossClient.getEndpoint().toString();

private OSSObjectUtils() {

}

/**
* 创建Bucket
*
* @param bucketName
* @throws OSSException
* @throws ClientException
*/
@SuppressWarnings("unused")
@Deprecated
private static void createBucket(String bucketName) throws OSSException, ClientException {
if (!ossClient.doesBucketExist(bucketName)) {
logger.info(ENDPOINTINFO + "创建bucketName:" + bucketName);
ossClient.createBucket(bucketName);
}
}

public static boolean isExistObject(String bucketName, String key) {
boolean result = false;
try {
result = ossClient.doesObjectExist(bucketName, key);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* 上传object
*
* @param bucketName
* @param key
* @param inputStream
* @throws OSSException
* @throws ClientException
*/
public static void putObject(String bucketName, String key, InputStream inputStream)
throws OSSException, ClientException {
logger.info(ENDPOINTINFO + "上传Object,bucketName=" + bucketName + ",key=" + key);
ossClient.putObject(bucketName, key, inputStream);
}

/**
* 上传object
*
* @param bucketName
* @param key
* @param inputStream
* @throws OSSException
* @throws ClientException
*/
public static void putObject(String bucketName, String key, File file) throws OSSException, ClientException {
logger.info(ENDPOINTINFO + "上传Object,bucketName=" + bucketName + ",key=" + key);
ossClient.putObject(bucketName, key, file);
}

/**
* 上传object,带元数据
*
* @param bucketName
* @param key
* @param inputStream
* @param meta
* @throws OSSException
* @throws ClientException
*/
public static void putObject(String bucketName, String key, InputStream inputStream, ObjectMetadata meta)
throws OSSException, ClientException {
logger.info(ENDPOINTINFO + "上传Object,bucketName=" + bucketName + ",key=" + key);
ossClient.putObject(bucketName, key, inputStream, meta);
}

/**
* 上传object,带进度listener
*
* @param bucketName
* @param key
* @param inputStream
* @param listener
* @throws Exception
*/
public static void putObject(String bucketName, String key, InputStream inputStream,
PutObjectProgressListener listener) throws Exception {
logger.info(ENDPOINTINFO + "上传Object,带进度监听,bucketName=" + bucketName + ",key=" + key);
ossClient.putObject(
new PutObjectRequest(bucketName, key, inputStream).<PutObjectRequest> withProgressListener(listener));
}

/**
* 签名url
*
* @author kira
* @param bucketName
* @param key
* @param expiration
*            有效期
* @return
*/
public static URL generatePresignedUrl(String bucketName, String key, Date expiration) {
logger.info(ENDPOINTINFO + "获取URL,bucketName=" + bucketName + ",key=" + key);
return ossClient.generatePresignedUrl(bucketName, key, expiration);
}

/**
* 获取object,并读取流输出至OutputStream<br>
* 用于流式下载
*
* @author kira
* @param bucketName
* @param key
* @param out
* @throws IOException
*/
public static void getObjectToOutputStream(String bucketName, String key, OutputStream out) throws IOException {
logger.info(ENDPOINTINFO + "获取Object,输出至OutputStream,bucketName=" + bucketName + ",key=" + key);
byte[] buf = new byte[1024];
InputStream in = ossClient.getObject(bucketName, key).getObjectContent();
int length = 0;
while ((length = in.read(buf)) > 0) {
out.write(buf, 0, length);
}

in.close();
out.close();
}

/**
* 获取Object的Byte<br>
* 由于读取整个object至内存,故大文件不建议使用此方法,容易内存溢出
*
* @author kira
* @param bucketName
* @param key
* @return
* @throws IOException
*/
public static byte[] getObjectByte(String bucketName, String key) throws IOException {
logger.info(ENDPOINTINFO + "获取Object的Byte,bucketName=" + bucketName + ",key=" + key);
byte[] buf = new byte[1024];
InputStream in = ossClient.getObject(bucketName, key).getObjectContent();
for (int n = 0; n != -1;) {
n = in.read(buf, 0, buf.length);
}
in.close();
return buf;
}

public static void main(String[] args){
/*List<Bucket> list= ossClient.listBuckets();
for(Bucket b:list){
System.out.println(b.getName());
}*/
//file/policyfile/236e7e90-0d9c-4fa7-b7f3-ffededb3f8d8.png
List<OSSObjectSummary> list=ossClient.listObjects("xsjyappstatic","file/policyfile/").getObjectSummaries();
for(OSSObjectSummary ossos:list){
System.out.println("##############################");
System.out.println(ossos.getKey());
//ossClient.deleteObject("jyjyimage", ossos.getKey());
}
//System.out.println(DateUtils.sdf_yMdHmsS.format(new Date()));
//System.out.println(ossClient.doesObjectExist("jyjyimage", "schoolbase-video/20170408134128185_WI4QUI105.mps4"));
}

}


工具类准备好后 我们着手写自己上传controller,基于项目代码,我们简单的看一下。

为了精简 删除了一下与上传无关的代码

2.上传controller

@ResponseBody
@RequestMapping("/upload")
public String Upload(HttpServletRequest request,
@RequestParam("uploadfile") MultipartFile uploadfile,
@RequestParam("comm") String comm,
@RequestParam("csrftoken") String csrftoken){
String csrftoken_serssion = (String)request.getSession().getAttribute(com.unisolution.xsjy.jyj.helpers.SessionKeys.CSRFTOKEN);

Users sessionuser = SessionHelperForLogin.getSessionUser(request.getSession());

Map<String, Object> returnmap = new HashMap<String, Object>();
returnmap.put("status", "0");
returnmap.put("msg", "文件上传失败");

if(dgradeTypes!=null&&dgradeTypes.length>0 && uploadfile!=null && StringUtils.equals(csrftoken_serssion, csrftoken)){

String key=OSSConfig.OBJECTKEY_PREFIX_FILE_POLICYFILE+UUID.randomUUID().toString()+"."+StringUtils.substringAfterLast(uploadfile.getOriginalFilename(), ".");
try {
//application/octet-stream
//ObjectMetadata meta=new ObjectMetadata();
//meta.setContentType("application/octet-stream");
OSSObjectUtils.putObject(OSSConfig.BUCKETNAME_XSJY_STATICSERVER, key, uploadfile.getInputStream());

PolicyFile policyFile=new PolicyFile();

policyFile.setFileNameOriginal(uploadfile.getOriginalFilename());

/*
*  FILE_SIZE
FILE_PATH //阿里云地址
FILE_PATH_CUSTOMDOMAIN //域名地址
FILE_PATH_RELATIVE//域名后缀的详细地址
www.ys.com/xsjy(bucketName)/file(key前缀)/asd51d1a.doc(uuid命名的)
*/
String file_path =OSSConfig.ENDPOINT_SHANGHAI+"/"+OSSConfig.BUCKETNAME_XSJY_STATICSERVER+"/"+key;
String file_path_customdomain =OSSConfig.CUSTOMDOMAIN_XSJY_STATICSERVER+"/"+key;
String file_path_relative="/"+OSSConfig.BUCKETNAME_XSJY_STATICSERVER+"/"+key;

policyFile.setFilePath(file_path);
policyFile.setFilePathCustomdomain(file_path_customdomain);
policyFile.setFilePathRelative(file_path_relative);
policyFile.setOssbucket(OSSConfig.BUCKETNAME_XSJY_STATICSERVER);
policyFile.setOssobjectkey(key);
//policyFile.setFileSize();
if(policyFileService.save(policyFile)){
returnmap.put("status", "1");
returnmap.put("msg", "文件上传成功");
}

} catch (OSSException e) {
logger.error(e.getMessage());
e.printStackTrace();
} catch (ClientException e) {
logger.error(e.getMessage());
e.printStackTrace();
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}

}else{
returnmap.put("msg", "非法访问");
}
System.out.println(JSONObject.toJSONString(returnmap));
return JSONObject.toJSONString(returnmap);
}
上面代码最主要是
OSSObjectUtils.putObject(OSSConfig.BUCKETNAME_XSJY_STATICSERVER, key, uploadfile.getInputStream());
OSSConfig.BUCKETNAME_XSJY_STATICSERVER:项目的静态服务器BUCKETNAME
OSSConfig.OBJECTKEY_PREFIX_FILE_POLICYFILE:key的前缀,BUCKETNAME后的文件夹
key:包含两个部分,前缀+文件名,文件名我才用的是UUID,避免出现同名问题。下载时通过之前保存的设置下载文件名
OSSObjectUtils.putObject()再传入流之后,上传就完成了。
但是为了保存一些属性方便以后下载使用。
FILE_PATH //阿里云地址
FILE_PATH_CUSTOMDOMAIN //域名地址
我选择一个测试文件来说明一下。
1)**FILE_PATH** :http://oss-cn-shanghai.aliyuncs.com/xsjyappstatic/file/policyfile/7ffd4732-5c54-45e6-b2d4-6553b3f5ccd1.jpg
2)**FILE_PATH_CUSTOMDOMAIN** :http://static01.xsjyapp.com/file/policyfile/7ffd4732-5c54-45e6-b2d4-6553b3f5ccd1.jpg

这两个地址都能访问到,只是阿里云地址会被一些DNS屏蔽。所以我们一般采用第二个,其实仔细可以发现。 http://oss-cn-shanghai.aliyuncs.com/xsjyappstatic==http://static01.xsjyapp.com 这之间是有映射关系的。
3)**FILE_PATH_RELATIVE**:
这个属性存储的是域名后的详细路径也就是两个地址相同的部分,如果以后更换项目域名,你会发现好处的。

再说下载


@RequestMapping(“/download”)//下载为html

public void download(HttpServletRequest request, HttpServletResponse response,

@RequestParam(“id”) Long id,

@RequestParam(“csrftoken”) String csrftoken) {

String csrftoken_serssion = (String) request.getSession().getAttribute(com.unisolution.xsjy.jyj.helpers.SessionKeys.CSRFTOKEN);
if(id!=null&&StringUtils.equals(csrftoken_serssion, csrftoken)){

PolicyFile policyFile=policyFileService.getByPrimaryKey(id);

if(policyFile!=null){
String extname=StringUtils.substringAfterLast(policyFile.getFileNameOriginal(), ".");
String encode_filename=StringUtils.substringBeforeLast(policyFile.getFileNameOriginal(), ".");
try {
//encode_filename=URLEncoder.encode(StringUtils.substringBeforeLast(policyFile.getFileNameOriginal(), "."), "UTF-8");
//encode_filename=new String(StringUtils.substringBeforeLast(policyFile.getFileNameOriginal(), ".").getBytes(),"UTF-8");
encode_filename=encode_filename.replace(" ", "");
encode_filename = new String(encode_filename.getBytes("GB2312"), "ISO8859-1");
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
encode_filename=String.valueOf(new Date().getTime());
}
response.reset();
//1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("application/octet-stream; charset=utf-8");
//2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf)
response.setHeader("Content-Disposition", "attachment; filename="+encode_filename+"."+extname);

OutputStream out=null;
try {
out=response.getOutputStream();
OSSObjectUtils.getObjectToOutputStream(policyFile.getOssbucket(), policyFile.getOssobjectkey(), out);
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}finally{
try {
out.close();
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}

}

}
}


encode_filename写了好几次主要是火狐的不兼容,没有办法解析转过的文件名,以及文件名出现空格所出现的文件名不完整。为了这个搞了好久,看见火狐就头疼。
catch中的文件名是为了防止程序出错按照日期来设置默认文件名。
response.setHeader()是设置消息头filename后面的按照你的需要来,其他的按照这样写就写,为什么我也不知道,规范。


OutputStreamout=response.getOutputStream();

OSSObjectUtils.getObjectToOutputStream(policyFile.getOssbucket(), policyFile.getOssobjectkey(), out);

“`

这里面其实是要try catch的 为了简洁。。。。

通过rep获取输出流对象,然后就是OSSObjectUtils.getObjectToOutputStream();

第一个参数是bucketname 就是项目域名后存放的文件夹名

第二次参数是key 就是设置路径+整个文件名。

第三个就是传入输出流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  阿里云
相关文章推荐