最近在做上传文件(主要是图片)的功能,因为在此过程中遇到了不少问题,在此做个总结。
一 环境
1 Jboss服务器:centos7
2 语言:Java
3 框架:springMVC
4 图片服务器:nginx
二 主要技术
为了降低Jboss服务器的IO操作,同时提高页面的加载速度,使用nginx服务器作为图片服务器,我们在上传图片时,将向Jboss服务器放置一张图片,同时向nginx服务器上传一张图片,同时将nginx服务器的图片路径存入数据库中,页面显示图片时,只需要按照数据库中的图片路径即可找到相关图片。
三 实现
1 前端HTML
<span style="font-size:18px;"> <span class="col-sm-2 control-label">个人头像</span>
<img id="imgCoursePoster" src="${pageContext.request.contextPath}/css/images/lecturer.jpg" />
<i class="icon-del" onclick="deleteCoursePoster()" title="移除"></i>
<input type="file" onchange="uploadCoursePoster();" id="fileCoursePoster" style="display: none;" name="fileCoursePoster" />
<span id="errorCoursePoster" style="color: red; display: none;">请上传图片!</span>
<input id="btnUploadPic" type="button" onclick="upLoad()" value="上传头像" class="btn btn-sm btn-normal"></span>
2 JavaScript
<span style="font-size:18px;"> function uploadCoursePoster() {
var imageType = document.getElementById("imageType").value;
var studentId=$("#studentId").val();
var sessionId = $("#sessionId").val();
$.ajaxFileUpload({
url : "/itoo-jrkj-student-web/media/uploadImages", // 需要链接到服务器地址
secureuri : false,
data : {
"studentId" : studentId,
"imageType" : imageType
},
fileElementId : "fileCoursePoster",// 文件选择框的id属性
dataType : 'json',
success : function(data) {
$("#imgCoursePoster").attr(
"src",
"http://123.56.120.25:8888/apple/"
+ data);
$('#headPic').val(data);
$.jqAlert({
title: '提示',
msg: '上传成功!',
sure: function() {
},
close: function() {
}
});
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
$.jqAlert({
title: '提示',
msg: '上传失败!',
sure: function() {
},
close: function() {
}
});
}
});
}</span>
3 Java代码
<span style="font-size:18px;"> @RequestMapping(value = "media/uploadImages", produces = "text/plain;charset=UTF-8")
@ResponseBody
public void uploadImages(HttpServletRequest request,
HttpServletResponse response) throws IllegalStateException,
IOException {
StringBuilder str = new StringBuilder("uploadImages-->");
// 上传到指定的文件夹中,imageType为文件夹的名字
String imageType = request.getParameter("imageType").toString(); //文件夹名,便于图片分类
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
String fileName = "";//图片的名字
Calendar date = Calendar.getInstance(); //以图片类别+日期规划图片文件夹层级
SimpleDateFormat format1 = new SimpleDateFormat("yyyy");
SimpleDateFormat format2 = new SimpleDateFormat("MM");
SimpleDateFormat format3 = new SimpleDateFormat("dd");
String year = format1.format(date.getTime());
String month = format2.format(date.getTime());
String day = format3.format(date.getTime());
// 上传的图片存储的路径,格式如下:
String uploadServicePath = "";
String filePath="";
String newFileName="";
for (Iterator it = multipartRequest.getFileNames(); it.hasNext();) {
String key = (String) it.next();
MultipartFile mulfile = multipartRequest.getFile(key);
fileName = mulfile.getOriginalFilename(); //获取上传图片的文件名,以便得到其在jboss中的路径
//str.append("fileName=").append(fileName).append("_");
//获取存在服务器下的图片的绝对路径
File getFilePath=new File(fileName);//要根据图片名字获取路径
filePath=getFilePath.getAbsolutePath();//获取Jboss服务器的保存路径
//把filePath的路径和文件名分开,便于存储 //jboss
String utfFilePath=URLEncoder.encode(filePath,"utf-8");
String lastFileName=utfFilePath.substring(utfFilePath.lastIndexOf("bin")+6,utfFilePath.length());
newFileName="/usr/local/uploadPicture/"+UUID.randomUUID().toString()+"/";
File createJbossFile=new File(newFileName);
if (!createJbossFile.exists()) {
createJbossFile.mkdir();
}
filePath=newFileName+lastFileName;
//str.append("filePath=").append(filePath).append("_");
File file = new File(filePath);
mulfile.transferTo(file);//保存
}
File imagefile = new File(filePath);
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("GBK");
String hostname = "********"; //FTP服务器主机ip
int port = 21;//FTP服务器端口,默认就是21
String username = "******"; //FTP服务器用户名(可以有多个)
String password = "******";//FTP服务器密码
try {
//链接ftp服务器
ftpClient.connect(hostname, port);
//登录ftp
ftpClient.login(username, password);
int reply = ftpClient.getReplyCode(); //ftp服务状态码
//如果reply返回230就算成功了,如果返回530密码用户名错误或当前用户无权限。
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
return ;
}
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 保存图片的相对路径到阿里云服务器
fileName=UUID.randomUUID().toString()+".jpg";//自定义图片名,也能防止汉字的干扰
uploadServicePath ="abc/" + imageType + "/" + year + "/"
+ month+day+"/"+fileName; //上传到服务器的路径
System.out.println("uploadServicePath:" + uploadServicePath);
//在nginx上创建文件夹,一次只能创建一级,所以建多级要分多次
ftpClient.makeDirectory("abc");//什么的都不写的情况下,默认在root目录下创建文件夹,此处在nginx/apple/uploadImage
ftpClient.makeDirectory("abc/"+imageType);//在root目录下创建文件夹
ftpClient.makeDirectory("abc/"+imageType+ "/" + year);//在root目录下创建文件夹
ftpClient.makeDirectory("abc/"+imageType+ "/" + year +"/"+month+day);//在root目录下创建文件夹
InputStream input = new FileInputStream(imagefile);
ftpClient.storeFile(uploadServicePath, input);//文件你若是不指定就会上传到root目录下
input.close();
ftpClient.logout();
} catch (SocketException e) {
System.out.println("SocketException(socket协议出错:):" + e.getMessage());
} catch (IOException e) {
System.out.println("IOException:(IO异常):" + e.getMessage());
}finally
{
if (ftpClient.isConnected())
{
try
{
ftpClient.disconnect();
} catch (IOException ioe)
{
str.append("ftrClient关闭异常-->IOException=").append(ioe.getMessage()).append("_");
}
}
}
// 根据id更新个人信息
Student student = new Student();
String studentId = request.getParameter("studentId");
student = studentBean.findStudentById(studentId, dataBaseName);
student.setDataBaseName(dataBaseName);
student.setHeadPic(uploadServicePath);
Boolean flag = studentBean.updateHeadPicture(student);
if (!flag) {
uploadServicePath = "error";
}
JacksonJsonUntil jacksonJsonUntil = new JacksonJsonUntil();
jacksonJsonUntil.beanToJson(response, uploadServicePath);
}</span>
效果图如下: