上传文件,界面如图:
点击上传图片,将会出现文件上传的窗口。接下来,给出代码:
首先,controller层给出上传文件的方法:
/**
* 上传附件
* @param file
* @param request
*/
@RequestMapping("/attachmentUpload.json")
@Security(mustLogin = true)
public void uplaod(@RequestParam("file") MultipartFile file,
HttpServletRequest request,
HttpServletResponse response) {
try {
String fileName = file.getOriginalFilename();
String convertName = feedbackSuggestionBizService.storeAttachment(fileName, file.getInputStream());
WebUtil.ajaxOutput(AjaxResult.newSuccessResult(convertName), response);
} catch (Exception e) {
log.error(e.getMessage(), e);
e.printStackTrace();
WebUtil.ajaxOutput(AjaxResult.newFailResult(null, "upload fail"), response);
}
}
其中,业务层service是feedbackSuggestionBizService。storeAttachment方法如下:
public String storeAttachment(String fileName, InputStream in) throws Exception {
//TODO 如果附件已存在,直接复用
// 往oss中写入新的附件
String ossName = feedbackSuggestionService.encodeFileName(fileName);
boolean uploadResult = ossUtil.uploadFile(in, ossName);
if (!uploadResult) {
throw new RuntimeException("保存简历失败.");
}
log.info("生成的OSSKEY : " + ossName);
return ossName;
}
ossUtil是阿里云工具类,uploadFile是上传文件的核心方法,代码如下
/**
* 上传文件
* @param resouce 文件输入流
* @param fileName 文件名(相对路径,不能以/开头)。名称在使用UTF-8编码后长度必须在 1-1023字节之间,而且不能包含回车、换行、以及xml1.0不支持的字符,同时也 不能以“/”或者“\”开头。
*/
public boolean uploadFile(InputStream resouce, String fileName) {
ObjectMetadata meta = new ObjectMetadata();
try {
meta.setContentLength(resouce.available());
PutObjectResult result = ossClient.putObject(bucketName, fileName, resouce, meta);
log.debug(result.getETag());
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("上传文件到OSS失败", e);
return false;
}
}
encodeFileName是将文件名加密的方法,可以避免文件重名,代码如下:
/**
* 加密图片路径
* @param fileName
* @return
* @throws UnsupportedEncodingException
*/
@Override
public String encodeFileName(String fileName) throws Exception{
String name = fileName.substring(0, fileName.lastIndexOf("."));
String postfix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
// String encodeName = new sun.misc.BASE64Encoder().encode(name.getBytes("UTF-8"));
// // mime协议的规定:base64.encodestring返回的字符串默认结尾带"\n",
// // 而且产生的base64编码字符串每76个字符就会用"\n"隔开,所以最安全的方法是用replace去掉其中所有的\n。且不影响decde
// encodeName = encodeName.replaceAll("\n", "");
String encodeName = URLEncoder.encode(name, "UTF-8");
// 为了防止同一家公司两个HR同事对人才上传了同名的附件,导致人才简历附件串掉,采用原始文件名拼接上当前时间拼3位随机数
encodeName = encodeName + "_" + System.currentTimeMillis()+"_"+(int)(Math.random()*1000);
log.debug("附件["+fileName+"]转换后的文件名:"+encodeName + postfix);
return encodeName + postfix;
}
相对于的解密方法:
/**
* 解密图片路径, 返回图片附件名称
* @return
* @throws UnsupportedEncodingException
*/
public String decodeFileName(String filePath) throws Exception {
if(StringUtils.isEmpty(filePath)){
return null;
}
String name = filePath.substring(0, filePath.lastIndexOf("."));
String postfix = filePath.substring(filePath.lastIndexOf("."), filePath.length());
// 去除尾部随机数
String decodeName = name.substring(0, name.lastIndexOf("_"));
// 取出尾部时间戳
decodeName = decodeName.substring(0, decodeName.lastIndexOf("_"));
// base64转码
// decodeName = new String(new sun.misc.BASE64Decoder().decodeBuffer(decodeName), "UTF-8");
// urlencode转码
decodeName = URLDecoder.decode(decodeName, "UTF-8");
log.debug("附件地址["+filePath+"]转换得到的原始文件名:"+decodeName + postfix);
return decodeName + postfix;
}