关于上传文件要踩的坑
程序员文章站
2024-03-13 09:04:03
...
前言:JavaWeb项目中经常会用到文件上传的这个功能,说白了,文件上传就是对流进行操作,常用的功能也就那么几个,但是还会经常性有点懵逼,经过一个项目的洗礼,终于稍微清晰一点了。
文件上传到哪里?
- 服务器的文件夹中
- 自己搭建的文件服务器
- 云存储
服务器的文件夹中
对于一些可靠性要求不高的项目,如果说上传的文件由于服务器挂掉而导致文件丢失没有什么影响的话,存到服务器的磁盘上也许是最简单的选择。而我在资源有限的情况下就选择了这种方式。
如何上传
上传的前端
html 使用的百度的webuploader插件
<div id="filePicker">选择图片</div>
<div id="result"></div>
js
var uploader = WebUploader.create({
swf: '/js/upload/Uploader.swf', //指定flash上传文件的位置
server: '', //上传文件服务器的地址
pick: '#filePicker', //文件选择按钮
fileVal: 'file',
auto: true,
fileSizeLimit: 10 * 1024 * 1024,
accept: {
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: 'image/*'
}
});
//文件进入上传队列
uploader.on('fileQueued', function (file) {
});
//上传前的判断处理
uploader.on('error', function (type) {
if (type === 'Q_TYPE_DENIED') {
layer.msg("请上传图片文件");
} else if (type == "F_EXCEED_SIZE") {
layer.msg("图片大小不能超过10M");
}
});
//文件上传进度事件
uploader.on('uploadProgress', function (file, percentage) {
});
uploader.on('startUpload', function () {
$("#result").html("");
});
//文件上传成功
uploader.on('uploadSuccess', function (file, response) {
if (!response.success) {
layer.alert(response.message);
} else {
layer.msg("上传成功");
}
});
//文件上传失败
uploader.on('uploadError', function (file) {
layer.msg("上传失败,服务器异常");
});
//无论上传成功还是失败
uploader.on('uploadComplete', function (file) {
setTimeout(function () {
window.history.go(0);
}, 1000)
});
后台接收
/**
* 上传头像并保存路径
*
* @param file
* @return
* @throws IOException
*/
@RequestMapping(value = "/demo/upload/picture", method = POST)
@ResponseBody
public Object picture(@RequestParam("file") MultipartFile file) {
Map<String, Object> result = new HashMap<String, Object>(INIT_MAP);
result.put(SUCCESS, false);
String userName = OperatorUtil.getOperator().getUsername();
try {
//获取文件的原始名称
String pictureName = file.getOriginalFilename();
//获取大小
Long size = file.getSize();
//文件的输入流
InputStream inputStream = file.getInputStream();
iploadBusiness.savePicture(candidate, inputStream, pictureName, size);
result.put(SUCCESS, true);
} catch (ServiceException ex) {
result.put(MESSAGE, ex.getMessage());
} catch (Exception e) {
logger.error("上传头像出错", e);
result.put(MESSAGE, "上传头像出错,请刷新后重试");
}
return result;
}
Service处理
appendixInfo是关于存储文件的一个对象,主要有存储路径,文件大小等字段
@Override
public void savePicture(InputStream inputStream, String pictureName, Long size) {
AppendixInfo appendixInfo = new AppendixInfo();
String strSize = FileUtils.byteCountToDisplaySize(size);
appendixInfo.setFileSize(strSize);
appendixInfo.setName(pictureName);
appendixInfo.setGmtCreate(new Date());
appendixInfo.setGmtModified(new Date());
appendixInfo.setType("img");
String saveName = UUID.randomUUID() + pictureName.substring((pictureName).lastIndexOf("."));
appendixInfo.setSaveName(saveName);
//限制文件大小
if (size > 1048576L) {
throw ServiceException.create(016, "图片大于1M", null);
}
File file = new File("这里放你要存储的文件夹");
if (!file.exists() && !file.isDirectory()) {
file.mkdir();
}
try (OutputStream outputStream = new FileOutputStream(new File(这里放你要存储的文件夹, pictureName))) {
IOUtils.copy(inputStream, outputStream);
appendixInfo.setFilePath(这里放你要存储的文件夹 + "/" + pictureName);
appendixInfoDao.savePicture(appendixInfo);
} catch (IOException e) {
throw ServiceException.create(007, "头像上传异常", null);
}
}
这个时候,基本上也就上传成功了。
搭建的文件服务器
为了文件的可靠性能够提升,通常会搭建分布式的文件服务器,例如fastDFS。这个东西之前是尝试搭过一次,但是现在也基本忘完了。
云服务商的镜像存储
例如阿里云的对象存储OSS,现在还可以免费试用,用起来还是很方便的。
需要注意的问题
- 如果使用上传后的文件如果要访问并能处理,通常是需要配置虚拟路径,这个时候你才能够在互联网访问到服务器磁盘上的资源。
虚拟路径的配置方式
找到tomcat中的server.xml文件
<Context path="/upload" docBase="D:\upload" reloadable="true" crossContext="true"></Context>
- 往磁盘中存文件的时候一定要重命名!!!!要不然如果上传的新文件和旧文件文件名相同,则旧文件就会被替换掉,而你一无所知,这个坑项目上线以后才得以踩成。代价太大了。。