发表于: 2017-11-01 23:48:56
1 779
今天完成的事情:
1. 通过tomcat上传文件
2. 写了一个操作oss配合spring 的工具类,未测试
明天计划的事情
1. 把oss和文件上传联系起来
2. 研究一下防盗链
遇到的问题:
1. 如果把图片链接设置为私有,而数据库里存在着图片链接
那么用户如何查看自己的图片???
收获
1. 通过tomcat上传文件
代码接昨天的:
try {
//使用ServletFileUpload解析器解析上传数据,
// 解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> list = upload.parseRequest(request);
for (FileItem item : list){
/*isFormField方法用来判断FileItem对象里面封装的数据是一个普通文本表单字段,
*还是一个文件表单字段。如果是普通文本表单字段,返回一个true否则返回一个false。
*因此可以用该方法判断是否是普通表单域还是文件上传表单域。
* 如果fileitem中封装的是普通输入项的数据
*/
if(item.isFormField()){
//getFieldName方法用来返回表单标签的name属性的值。
String name = item.getFieldName();
//解决普通输入项的数据的中文乱码问题
String value = item.getString("UTF-8");
loggerUplFilSer.info(name + " = "+ value);
}
//如果fileitem中封装的是上传文件
else {
//得到上传的文件名称
String fileName = item.getName();
loggerUplFilSer.info("file name : " + fileName);
/*
* String.trim()去掉字符串两端的多余的空格以及:
*('/t', '/n', '/v', '/f', '/r', ' ', '/x0085', '/x00a0',
* ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
* ' ', '?', '/u2028', '/u2029', ' ', '?')
*/
if(fileName==null || fileName.trim().equals("")){
continue;
}
/*
*注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,
* 如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
* 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
*/
//截取掉从首字母起长度为filename.lastIndexOf("\\")+1的字符串,将剩余字符串赋值给filenam e ;
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
// 得到上传文件的扩展名
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
loggerUplFilSer.info("fileExt: " + fileExt);
int sign = 0;
// 检查扩展名
for(String str : Picture_Ext_Name){
//检查字符串(参数parameterValue)是否包含字符串(参数str), 忽略大小写.返回类型booleanif(StringUtils.containsIgnoreCase(fileExt,str)){
sign = 1;
}}
if(sign == 0){
out.write("<script charset=\"utf-8\" language='javaScript'> alert('图片类型非法');</script>".getBytes());
loggerUplFilSer.info("上传文件扩展名是不允许的扩展名:" + fileExt);
return;
}
//重新给文件命名
String user = CookieUtils.getCookie(request,"user");
String time = String.valueOf(System.currentTimeMillis());
int random = ThreadLocalRandom.current().nextInt(999999);
/* 命名规则: u:username time: 当前时间戳 r: 随机6位数 f: 文件名*/
fileName = "u_" + user + "-t_" + time + "-r_" + random + "-f_" + fileName;
loggerUplFilSer.info("new file name : " + fileName);
//获取item中的上传文件的输入流
InputStream in = item.getInputStream();
//创建一个缓冲区
byte buffer[] = new byte[1024];
//判断输入流中的数据是否已经读完
int len = 0;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
while((len=in.read(buffer))>0){
//创建一个文件输出流
FileOutputStream outFile = new FileOutputStream(savePath + "\\" + fileName);
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
outFile.write(buffer, 0, len);
//关闭输出流
outFile.close();
}
//关闭输入流
in.close();
//删除处理文件上传时生成的临时文件
item.delete();
}
2. 写了一个操作oss配合spring 的工具类,未测试
private static void inti(){
if (ossClient != null) {
return;
}
if (ossClient == null) {
ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, clientConfiguration);
}
if(ossClient.doesBucketExist(bucketName)){
loggerAliOss.info("您已经创建Bucket:" + bucketName + "。");
}
else{
loggerAliOss.info("您的Bucket不存在,创建Bucket:" + bucketName + "。");
// 创建Bucket。
ossClient.createBucket(bucketName);
}
}
private AliYunOssUtil(){
}
/**
* @Description: uploadStream 上传一个is流
* @author Jecced
* @param path oss路径
* @param name 文件名
* @param is is输入流
* @param contentType 手动设置文件类型:image/png等
* @return
*/
public static void uploadStream(String path, String name, InputStream is, String contentType) {
try {
//开启一个链接inti();
String firstKey = path + "/" + name;
firstKey = String.format(firstKey);
int count = 0;
//保证流传输到
try {
while (count == 0) {
count = is.available();
}
} catch (IOException e) {
e.printStackTrace();
loggerAliOss.error("IO传输错误");
}
/*
* 每上传一个Object,都需要指定和Object关 联的ObjectMetadata
* ObjectMetaData是用户对该object的描述,由一系列name-value对组成;
* 其中 ContentLength是必须设置的,以便SDK可以正确识别上传Object的大小。
* Put Object请求处理成功后,OSS会将收到文件的MD5值放在返回结果的ETag中。
* 用户可以根据ETag检验上传的文件与本地的是否一致。
*
* 如果上传文件还要设置ContentLength: meta .ContentLength(file.length())
*/
ObjectMetadata meta = null;
if (contentType != null) {
meta = new ObjectMetadata();
//设置上传的文件类型
meta.setContentType(contentType);
//设置流的长度
meta.setContentLength(count);
}
ossClient.putObject(bucketName, firstKey, is, meta);
ossClient.shutdown();
}
catch (OSSException oe) {
oe.printStackTrace();
} catch (ClientException ce) {
ce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
ossClient.shutdown();
}
}
}
当进行流的传输时,有可能因为网路堵塞,已经相应了,但文件数据还没有传输完成或者获取长度为0,
当用
InputStream.available();
方法时,可能出错,解决办法一下几种
1. 解决获取为0的办法
以上代码黄字
2. 不知道是否传完
A. 从http请求头里获取文件大小长度
B. 将最后一个字符设置为-1 当检测到时候,结束传输。但是有一个问题,网路为分组传输,如果最后的先达到岂不是错误了,难道是控制传输顺序的不是由JAVA控制,而是由网络层控制,只有这样说的同。
3. 设置一个缓冲区,当缓存完成就可以进行下一步。(首先要获取到文件长度来限定)
进度:
任务开始时间:10.30
预计完成时间:11.6
暂无延期风险
禅道:http://task.ptteng.com/zentao/project-task-264.htm
评论