文件上传:
【有时前端直接调用阿里云的一些方法,将base64Codes转成了后端可以直接保存的字符串,这种情况真是良心啊】
上传图片或者文件过大,这个时候我们就要选择压缩文件,把base64Codes当成一个字符串传到服务器即可.
1.文件太大前端传入 base64Codes 字符串:
可以经过前端处理,只上传一个base64Codes,这样后端按String接收就行了:
注意点:
前端传来的是base64字符串【 vo.getFile() 】,
后端的service层:
经过一些处理要得到一个MultipartFile类型的文件:BASE64DecodedMultipartFile.base64ToMultipart(vo.getFile())
然后将这个 MultipartFile 文件传入 uploadFile 方法中,最终得到一个String
String end = this.uploadFile(BASE64DecodedMultipartFile.base64ToMultipart(vo.getFile()));
BASE64DecodedMultipartFile:自定义的类,
uploadFile:自定义的函数
public class BASE64DecodedMultipartFile implements MultipartFile {
private final byte[] imgContent;
private final String header;
public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(";")[0];
}
@Override
public String getName() {
// TODO - implementation depends on your requirements
return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
}
@Override
public String getOriginalFilename() {
// TODO - implementation depends on your requirements
return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
}
@Override
public String getContentType() {
// TODO - implementation depends on your requirements
return header.split(":")[1];
}
@Override
public boolean isEmpty() {
return imgContent == null || imgContent.length == 0;
}
@Override
public long getSize() {
return imgContent.length;
}
@Override
public byte[] getBytes() throws IOException {
return imgContent;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(imgContent);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
new FileOutputStream(dest).write(imgContent);
}
public static MultipartFile base64ToMultipart(String base64) {
String[] baseStrs = base64.split(",");
// BASE64Decoder decoder = new BASE64Decoder();
byte[] b = Base64.decodeBase64(baseStrs[1]);
// new byte[0];
// b = decoder.decodeBuffer(baseStrs[1]);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
return new BASE64DecodedMultipartFile(b, baseStrs[0]);
}
}
private String uploadFile(MultipartFile file) {
String end = null;
try {
String fileName = ossUtil.uploadFile(file);
log.info(fileName);
//有效期为一年
end = ossUtil.getURL(fileName, new Date(new Date().getTime() + 1000 * 3600 * 24 * 365));
} catch (Exception e) {
log.error(e.getMessage());
}
return end;
}
uploadFile函数中使用了 AliyunOSSUtil 【要看看阿里云oss文档:https://www.jianshu.com/p/1be6bf51566f】
注意:这里面有些敏感信息一律用了:xx,所以不能直接使用
package com.lezhi.utils;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyun.oss.model.PutObjectResult;
import com.lezhi.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @ClassName AliyunOSSUtil
* @Description: TODO
* @Author liuhang
* @Date 2020/5/28
* @Version V1.0
**/
@Component
public class AliyunOSSUtil {
@Value("${info.aliyun.oss.key_id}")
private String KEY_ID;
@Value("${info.aliyun.oss.key_secret}")
private String KEY_SECRET;
@Value("${info.aliyun.oss.bucket}")
private String BUCKET;
@Value("${info.aliyun.oss.web_end}")
private String WEB_END;
public String getBasePath(String url) {
String endPoint = "http://" + BUCKET + WEB_END + "/";
url = url.substring(endPoint.length());
if (url.indexOf("?") > 0) {
url = url.substring(0, url.indexOf("?"));
}
return url;
}
public String getTempUrlByOldUrl(String oldUrl) {
try {
String path = getBasePath(oldUrl);
OSSClient client = getClient();
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
URL url = client.generatePresignedUrl(BUCKET, path, expiration);
client.shutdown();
return url.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return oldUrl;
}
public String getAssetsTempUrl(String path) {
if (path == null) return null;
try {
String bucketName = "lz-assets";
String endPoint = "https://xxx" + WEB_END;
OSSClient client = new OSSClient(endPoint, KEY_ID, KEY_SECRET);
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
URL url = client.generatePresignedUrl(bucketName, path, expiration);
client.shutdown();
return url.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public String getTempUrlByOldUrl(String oldUrl, int weight) {
try {
String endPoint = "http://" + BUCKET + WEB_END;
OSSClient client = new OSSClient(endPoint, KEY_ID, KEY_SECRET);
String path = getBasePath(oldUrl);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(BUCKET, path);
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
request.setExpiration(expiration);
request.setMethod(HttpMethod.GET);
request.setProcess("image/resize,w_" + weight + ",m_lfit");
URL url = client.generatePresignedUrl(request);
return url.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return oldUrl;
}
/**
*
* 原图片太大,缩减图片大小
* @param path
* @param
* @return
*/
public String getSignTempUrl(String path,int weight) {
try {
String endPoint = "http://" + BUCKET + WEB_END;
OSSClient client = new OSSClient(endPoint, KEY_ID, KEY_SECRET);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(BUCKET, path);
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
request.setExpiration(expiration);
request.setMethod(HttpMethod.GET);
request.setProcess("image/resize,w_" + weight + ",m_lfit");
URL url = client.generatePresignedUrl(request);
return url.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return path;
}
public String getSignTempUrl(String path) {
if (path == null) return null;
try {
OSSClient client = new OSSClient("https://" + BUCKET + WEB_END, KEY_ID, KEY_SECRET);
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
URL url = client.generatePresignedUrl(BUCKET, path, expiration);
client.shutdown();
return url.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public String getURL(String name) {
return getURL(name, null);
}
public String getURL(String name, Date date) {
if (StringUtils.isEmpty(name)) return null;
String endPoint = "http://" + BUCKET + WEB_END;
OSSClient client = new OSSClient(endPoint, KEY_ID, KEY_SECRET);
URL url = client.generatePresignedUrl(BUCKET, name, date == null ? (new Date(new Date().getTime() + 1000l * 3600l * 24l * 365l * 10l)) : date);
client.shutdown();
if (url != null) {
return url.toString();
}
return null;
}
public String uploadFile(File file) {
if (file == null) return "";
String name = file.getName();
String objectName = getName(name);
OSSClient client = getClient();
PutObjectResult result = getClient().putObject(BUCKET, objectName, file);
client.shutdown();
return objectName;
}
public String uploadFile(MultipartFile file) throws IOException {
if (file == null) return "";
String name = file.getOriginalFilename();
String objectName = getName(name);
OSSClient client = getClient();
PutObjectResult result = getClient().putObject(BUCKET, objectName, file.getInputStream());
client.shutdown();
return objectName;
}
private String getName(String name) {
String suffix = name.substring(name.lastIndexOf("."));
String finalFileName = System.currentTimeMillis() + suffix;
String objectName = getDir() + finalFileName;
return objectName;
}
private String getDir() {
Calendar calendar = Calendar.getInstance();
return calendar.get(Calendar.YEAR) + "/" + (calendar.get(Calendar.MONTH) + 1) + "/" + calendar.get(Calendar.DATE) + "/";
}
private OSSClient getClient() {
String endPoint = "http://" + BUCKET + WEB_END;
return new OSSClient(endPoint, KEY_ID, KEY_SECRET);
}
public Map<String, String> getAccess() {
String endPoint = "https://" + BUCKET + WEB_END + "/";
String callbackUrl = "https://xxxx.xxxx.com/api/learn/aliFile/callback";
OSSClient client = new OSSClient(endPoint, KEY_ID, KEY_SECRET);
Map<String, String> respMap = new LinkedHashMap<String, String>();
String dir = getDir();
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
java.sql.Date expiration = new java.sql.Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = client.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = client.calculatePostSignature(postPolicy);
respMap.put("accessid", KEY_ID);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", endPoint);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
JSONObject jasonCallback = new JSONObject();
jasonCallback.put("callbackUrl", callbackUrl);
jasonCallback.put("callbackBody",
"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
// jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
respMap.put("callback", base64CallbackBody);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return respMap;
}
}
2.直接上传一个file:
后端用 MultipartFile 接收,当然 也可以定义一个类,MultipartFile作为一个属性
public class NewReqUploadWorksVo {
private MultipartFile File;
private String xx;
private Integer xx;
}
使用第二种注意点:
1.使用 @PostMapping 和 在形参中使用 @RequestBody ,否则可能会接收不到
2.在service层处理 file:
3.也是要 使用 uploadFile()函数,只是 不用 base64 了。
3.返回给前端图片路径:
经过上述途径 ,保存在数据库中的图片不能直接在浏览器上访问
需要在返回给前端前,将返回类的图片路径进行处理 【我是在service层进行处理的】
private List<Vo> praseList(List<Vo> list){
list.forEach(e -> {
if (e.getWorks().indexOf("http") > -1) {
e.setWorks(ossUtil.getTempUrlByOldUrl(e.getWorks()));
} else {
JSONArray array = JSONArray.parseArray(e.getWorks());
if (array != null && array.size() > 0)
e.setWorks(ossUtil.getURL((String) array.get(0)));
}
});
return list;
}
vo类 是返回给前端的类 ,
若只是返回单个类:
if (vo.getWorks().indexOf("http") > -1) {
vo.setWorks(ossUtil.getTempUrlByOldUrl(vo.getWorks()));
} else {
JSONArray array = JSONArray.parseArray(vo.getWorks());
if (array != null && array.size() > 0)
vo.setWorks(ossUtil.getURL((String) array.get(0)));
}