传统的文件上传方式就是将文件直接上传保存到项目服务器中,这样做有以下几个缺点:
1.容错性差,如果服务器出现问题有可能导致上传文件丢失
2.占用服务器资源,上传文件过多会大量消耗服务器资源导致系统性能下降
3.不适应于集群环境,有可能出现上传与下载不在同一个服务器中。
传统的文件上传方式很明显不适用与互联网项目,解决方案就是使用第三方服务器存储上传文件。fastDFS是阿里巴巴开发的开源的轻量级分布式文件系统,具有高可用、高并发、可拓展的优点,符合互联网项目的需求。
fastDFS分布式文件系统的特点:
1.作为第三方服务器分布式文件系统存储文件,提高了容错性
2.上传与下载统一在fastDFS进行,解决了集群资源共享问题
3.浏览器访问远程服务器图片或静态页面时,需要遵循http协议,可以通过ngnix作为http服务器访问fastDFS的资源。
fastDFS在项目中实现文件上传的环境要求:
1.jar包(pom导入坐标) commos-io commos-fileupload fastDFS-client
2.配置文件上传解析器(在springmvc中配置)
3.客户端配置client.conf连接fastDFS服务器
附上项目图片上传部分代码:
前端页面部分
"easyui-linkbutton file" iconCls="icon-upload" >
function doUploadPhoto(){
if ($('#upload_form').form('validate')) {
var form = new FormData($("#upload_form")[0]);
var indexCode=$("#indexCode").val().trim();
$.ajax({
type: 'post' ,
url:"<%=path%>/uploadPhotoPG?indexCode="+indexCode,
cache:false ,
data:form ,
dataType:'json',
processData:false,
contentType:false,
success:function(result){
$.messager.show({
title:"提示信息",
msg:"上传成功"
});
setTimeout("location.reload(true)",1000);
},
error:function(result){
$.messager.show({
title:"提示信息",
msg:"未知错误"
});
}
});
}
}
请求跳转Controller部分
@ResponseBody
@RequestMapping(value = "/uploadPhotoPG", method = { RequestMethod.POST})
@Transactional(propagation=Propagation.REQUIRED)
public Object uploadPhotoPG(MultipartFile file,String checkId,String appMenuCode,String storeyId,String indexCode) {
try{
UploadLocalOrWeb uploadLocalOrWeb = new UploadLocalOrWeb();
String suffix = file.getOriginalFilename().split("\\.")[file.getOriginalFilename().split("\\.").length-1];
String url = uploadLocalOrWeb.uploadWeb(file.getBytes(), suffix);
Photo photo = new Photo();
photo.setId(UuidUtil.create());
photo.setIndexCode(indexCode);
photo.setUrl(url);
photo.setUploadtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
photo.setIsWriteReport("Y");
photoService.create(photo);
msg="上传成功";
code= "1";
map.put("msg", msg);
map.put("code", code);
}catch(Exception e){
//回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
e.printStackTrace();
msg="上传失败";
code= "-1";
map.put("msg", msg);
map.put("code", code);
}
return map;
}
fastDFS工具类(实现上传功能)
package com.ra.fastdfs;
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
/**
* 上传控制
* 选择上传到本地 或是 上传到远程服务器
* @author MrC
*
*/
public class UploadLocalOrWeb {
//远程服务器地址
@SuppressWarnings("unused")
private static String proxy_server = "121.15..";
@SuppressWarnings("unused")
private static String http = "http://";
//选择从本地项目下载还是从远程服务器下载文件
private static String LoadFromLocalOrWeb = "web";
/**
* 读取配置文件
* @throws Exception
*/
private void loadProperty() throws Exception {
Properties prop=new Properties();
InputStream is = this.getClass().getResourceAsStream("/fastdfs.properties");
prop.load(is);
is.close();
proxy_server = prop.getProperty("proxy_server").trim();
LoadFromLocalOrWeb = prop.getProperty("LoadFromLocalOrWeb").trim();
}
/**
* 上传到本地
* @param buffer 上传的文件数组
* @param path 如:D://upload/
* @param fileExtName 如:"doc"
* @param fileName 如:"image1"
* @return
*/
public String uploadLocal(byte[] buffer, String reqPath, String folder, String fileExtName, String fileName)throws Exception{
String path = reqPath + File.separator + folder;
String url = "";
String filePathName = "";
File file = new File(path);
if (!file.exists()) { //判断文件夹是否存在,如果不存在则创建文件夹
file.mkdir();
}
FileAndByte fab = new FileAndByte();
filePathName = fileName + FileUtils.randomName(fileExtName);
fab.byte2File(buffer, path, filePathName);
url = folder + File.separator + filePathName;
return url;
}
/** 上传到远程服务器
* @throws Exception **/
public String uploadWeb(byte[] buffer,String fileExtName) throws Exception{
FastDFSClient client = new FastDFSClient();
String url,url2 = "";
//调用远程服务器保存文件,返回文件保存url
url2 = client.upload(buffer,fileExtName);
//url = http + proxy_server +":7788"+ File.separator + url;
url = ReadPropertyUtil.getInstance("fastdfs.properties").getProperty("proxy_server").trim();
String str = ReadPropertyUtil.getInstance("fastdfs.properties").getProperty("http.tracker_server_port").trim();
url = "http://"+url + ":" + str + File.separator + url2 ;
return url;
}
/**
* @desc 图片压缩上传
* 先上传到本地,再压缩,再上传到图片真正上传的位置
* @author MrC
* 实际上传地址 reqPath + folder
* @param buffer 上传的文件数组 ***必需
* @param reqPath 如: D://images/ ***上传到本地必需 request.getServletContext().getRealPath("/")
* @param folder 如: upload/case/ ***上传到本地必需 上传文件夹
* @param fileName 如:"image1" ***上传到本地必需
* @param fileExtName 如:"doc" ***上传到远程服务器必需
* @throws Exception
*/
public String compressImgAndUpload(byte[] buffer, String reqPath, String folder, String fileExtName, String fileName) throws Exception{
String url = "";
FileUtils fu = new FileUtils();
FileAndByte fab = new FileAndByte();
// 缓存图片
url = uploadLocal(buffer, reqPath, "upload/cache", fileExtName, fileName);
// 压缩图片
fu.compressPic(reqPath+File.separator+url);
// 压缩后的缓存图片 转成 byte[] 以便上传到文件服务器
byte[] buff = fab.File2byte(reqPath+File.separator+url);
// 调用远程服务器保存文件,返回文件保存url
url = DoUpload(buff, reqPath, folder, fileExtName, fileName);
return url;
}
/**
* 上传到本地或是远程服务器
* 实际上传地址 reqPath + folder
* @param buffer 上传的文件数组 ***必需
* @param reqPath 如: D://images/ ***上传到本地必需 request.getServletContext().getRealPath("/")
* @param folder 如: upload/case/ ***上传到本地必需 上传文件夹
* @param fileName 如:"image1" ***上传到本地必需
* @param fileExtName 如:"doc" ***上传到远程服务器必需
* @return
* @throws Exception
*/
public String DoUpload(byte[] buffer, String reqPath, String folder, String fileExtName, String fileName) throws RuntimeException{
String url = "";
try {
loadProperty();//读取配置文件
if(LoadFromLocalOrWeb.equals("web")){
//上传至远程服务器
url = uploadWeb(buffer, fileExtName);
}else{
//上传至项目路径
url = uploadLocal(buffer, reqPath, folder, fileExtName, fileName);
}
} catch (Exception e) {
throw new RuntimeException();
}
return url;
}
}