上传图片文件至FTP服务器Ajax multipart formData FTP
最近在公司接手一个图片上传的功能实现,但需要上传保存在FTP服务器长久保存。解决Tomcat下保存,重启就会清空了的问题。既然是做测试,就在自己电脑搭建一个FTP服务器就好。FTP服务器如何在个人笔记本电脑搭建后续介绍,今天先来看这个功能代码如何写。
提交上传图片,同时还有两个其他数据需要提交
1. html页面
<html>
<head>
</head>
<body>
<form id="form_fj" enctype="multipart/form-data">
<div><!--此处上传一个id值 -->
<input type="text" id="hidden_jtbm"/>
</div>
<div id="divselect"> <!-- 该下拉框可以选择两种类型照片上传,根据数据库表业务逻辑来的,不必深究-->
选择身份
<select id="select_fj">
<option value ="1">小哥哥照片</option>
<option value ="2">小姐姐照片</option>
</select>
</div>
<div id="filePicker" class="uploader-list"><!--选择需要上传的图片 -->
<input type="file" id="zjfile" name="zjfj" multiple="multiple"/>
</div>
<div><input type="button" value="上传" id="doUpload" /></div>
<form>
</body>
</html>
注意:form表单需标明enctype=”multipart/form-data”
input输入框type属性写为file
2. js代码
// 附件上传函数
$(function(){
$("#doUpload").on('click',function(event){
var formData = new FormData();
var jtbm = $("#hidden_jtbm").val();
var zjlx = $("#select_fj").val();
<!--此部分若不懂,往下看解释-->
formData.append("jtbm",jtbm);
formData.append("zjlx",zjlx);
formData.append("file",$("#zjfile")[0].files[0]);
$.ajax({
url : rootUri + 'up/fjUpload.json',//你自己的url地址
type : 'post',
data : formData,
cache : false,
processData : false,
contentType : false,
async : false,
success : function(d) {
alert("上传成功");
}
})
})
})
注意:1.遇到表单中图片需要跟表单一起提交,这样会造成后台没办法接收到图片。因为表单提交时是默认application/x-www-form-urlencoded格式,只接受键值对。所以我们采用FormData格式异步提交表单,因为formData格式可以接收文件格式。
2.创建一个formData对象并向其中添加键值对,这个值可以是一个文件。("#zjfile")[0]是取出id=zjfile的元素,至于为什么是[0],这是因为jquery对象都有一个默认为0的索引用来取出其Dom元素*,***
("#zjfile")[0]是取出id=zjfile的元素,至于为什么是[0],这是因为jquery对象都有一个默认为0的索引用来取出其Dom元素*,***
(‘formData’)是一个jquery对象,[0]为Dom元素 可以用dom的所有属性和方法**。然后使用files来取出文件。这里我使用了files[0]还可以继续写files[1]等等,可以实现上传多个文件,我这里只上传了一个。然后服务器就可以接收文件了,和表单一样的接收方法。
3.
- cache : false,因为上传文件不需要缓存
- processData : false,因为data值是FormData对象,不需要对数据做处理。
- contentType设置为false。因为是由表单构造的FormData对象,且已经声明了属性enctype=”multipart/form-data”,所以这里设置为false。
3.Controller代码
/**
* 上传图片文件方法
* @param m 包含附件路径的Model类
* @param file 文件
* @param request
* @return
*/
@RequestMapping(value="/fjUpload.json" ,method=RequestMethod.POST)
@ResponseBody
public ResponseModel fjUpload(@RequestParam("file") MultipartFile file,HttpServletRequest request){
PersonModel m = new PersonModel(); //自己的Model类,与我自己的业务逻辑处理有关
ResponseModel model = new ResponseModel(); //自己封装的一个返回对象,可忽略。
//获取jtbm
String jtbm = request.getParameter("jtbm");
//获取zjlx
String zjlx = request.getParameter("zjlx");
Integer intZjlx = Integer.parseInt(zjlx);
//获取到文件名
String fileName = file.getOriginalFilename();
//将MultipartFile转换成流的形式存储
InputStream in = file.getInputStream();
//上传图片到ftp,获得服务器路径
String serverPath = doSavePhoto(in,fileName);
/*此处做自己的业务逻辑处理,可忽略*/
//根据jtbm获取到该MraModel列表
List<Map<String, Object>> list = daoHandler.executeSelectMoreSQL(sqlQuery("T_BD_BR_MRA",jtbm));
if(intZjlx == 1){
DatabaseTable dbt = new DatabaseTable(PersonModel.class);
//循环遍历每一条记录,并执行更新语句
for(Map<String,Object> map :list){
//将map结果集转换成POJO对象
m = (personModel) dbt.convertMap2POJO(map);
m.setNfsfzfj(serverPath);
daoHandler.update(m);
}
}
model.success();
}catch(Exception e){
e.printStackTrace();
system.out.println("Controller:发生异常!");
model.error();
}
return model;
}
/**
* 保存图片至ftp服务器
* @param in input流
* @param 图片名称
* @return 服务器路径
*/
public String doSavePhoto(InputStream in,String fileName){
String serverPath = null;
try{
String wjm = DateUtil.nowTimestamp() + fileName.substring(fileName.lastIndexOf('.'));//图片以时间命名
<!-- FtpConection单独建一个类-->
FtpConection conection = new FtpConection(ftp服务器IP地址, ftp服务器端口, ftp服务器用户名, ftp服务器密码);
//上传文件到服务器
serverPath = wjm;
boolean flag = conection.uploadFiles(in, serverPath);<!--uploadFiles为一个方法,继续看-->
conection.logout();
if (flag) {
System.out.println("FTP存储成功!");
} else {
System.out.println("FTP存储出错!");
}
}catch(Exception e){
e.printStackTrace();
System.out.println("Controller:上传ftp图片发生异常!");
}
return serverPath;
}
注意:
- 在doSavePhoto(in,fileName);时,我把file类型转换成了InputStream流,这与我自己后面封装的FtpConection类、uploadFiles方法有关。先这么做好了。
4 辅助工具类即FtpConnection
/**
* FTP服务器连接,用于访问FTP服务器,实现常用的创建目录、删除目录、上传文件、下载文件等操作。
*/
public class FtpConection {
/**
* 文件上次的缓存区大小
*/
private static final int BUF_SIZE = 1024*1024;
private String hostname;
private Integer port;
private String username;
private String password;
/**
* 创建一个与FTP服务器的连接。
* @param url 服务器IP地址
* @param prot 服务端口
* @param username 用户名
* @param password 密码
*/
public FtpConection(String url, Integer prot, String username, String password) {
this.hostname = url;
this.port = prot;
this.username = username;
this.password = password;
client = new FTPClient();
try {
client.connect(hostname, port);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
logger.error("FtpConection:链接FTP服务器发生异常!");
}
try {
client.login(username, password);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
logger.error("FtpConection:登陆FTP服务器发生异常!");
}
}
/**
* 利用流 上传文件
* @param in 本地流
* @param serverPath 服务器路径
* @return True 文件上传成功,False 文件上传失败
* @throws IOException
*/
public boolean uploadFiles(InputStream in, String serverPath) throws IOException {
boolean result = false;
client.setFileType(FTP.BINARY_FILE_TYPE);
client.enterLocalPassiveMode();
client.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
client.setBufferSize(BUF_SIZE);
//此处可以解释 为什么把file装换成了InputStream流
InputStream local = null;
try {
local = in;
result = client.storeFile(serverPath, local);
} finally {
if (local != null) {
local.close();
}
}
return result;
}
/**
* 退出已登录的FTP用户
* @return Boolean值,true-退出成功,false-退出失败(连接为登录)。
* @throws IOException
*/
public boolean logout() throws IOException {
return client.logout();
}
}
到此为止,点击上传图片,就可以在你的ftp文件夹下看到上传的图片,经过Controller层的业务逻辑处理,可以把ftp服务器中的图片路径保存在数据库。检查一下你的数据库,检查一下你的ftp服务器文件夹。
对于如何访问到ftp服务器上的图片,下篇文章在做介绍。