最近做了一个图片上传功能:功能演示图如图:
图片框展示图片,”上传图片“按钮上传图片,点击按钮,打开如下框:
点击选择文件后,再点击提交,文件上传成功,自动关闭当前页面,返回上一个页面,显示图片。因为当初时间比较紧,所以为了应付功能,就先这样做了。
后来时间较为充裕些,觉得一个上传操作这么多操作未免太繁杂了,客户体验不好,所以就决定用网上很流行的一些上传控件来做,希望可以简化部分操作,提高可操作性。
在网上找了几个插件后,考虑到游览器的兼容性,所以决定用uploadify插件做上传,好 了,下面说说我使用过程中遇到的一些麻烦吧。
官网下载uploadify插件:http://www.uploadify.com/ 我用的是最新版本(附件我也会把我的插件贴出来,应为修改过一些东西),还有一个问题:就是下载的插件包里面没用swfobject.js 这个js文件,这个要自己下载添加进去(注意)。
准备工作已经做好了,当然jquery是必不可少的,我用的是比较稳定的1.8版本。
先贴代码:(引用文件头)
<link rel="stylesheet" type="text/css" href=""/>
这个事用来解决游览器兼容性问题的。
<link rel="stylesheet" type="text/css" href="<%=contextPath%>/skin/blue/css/dialog.css"/>
<script type="text/javascript" src="<%=contextPath%>/mgr/oms/catentry/catentryInfo.js"></script>
<script type="text/javascript" src="<%=contextPath%>/js/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="<%=contextPath%>/js/kindeditor.js"></script>
<script type="text/javascript" src="<%=contextPath%>/tools/xheditor/xheditor-1.1.7-zh-cn.min.js"></script>
<script type="text/javascript" src="<%=contextPath%>/js/uploader/swfobject.js"></script>
<script type="text/javascript" src="<%=contextPath%>/js/uploa
<script type="text/javascript">
$(document).ready(function() {
if (window.navigator.userAgent.indexOf("MSIE")>=1)
{
//如果浏览器为IE
document.getElementsByTagName("link")[0].href="<%=contextPath%>/js/uploader/uploadify2.css";
}
else{
document.getElementsByTagName("link")[0].href="<%=contextPath%>/js/uploader/uploadify.css";
}
$("#uploadify").uploadify({
'auto' : true,
'swf' : '<%=contextPath%>/js/uploader/uploadify.swf',
'uploader' : '<%=contextPath%>/scripts/uploadify',//后台处理的请求 <%=contextPath%>/scripts/uploadify
'fileDataName' :'picFileData',
'fileTypeDesc' : '图片格式文件',
'fileTypeExts' : '*.png;*.jpg', //控制可上传文件的扩展名,启用本项时需同时声明fileDesc
'multi' : false,
'buttonText' : '<span class="upFtp">上传图片</span>',
onUploadSuccess :function(file,data,response){
alert(data);
alert(this.button.parent().attr("id"));
this.button.parent().parent().find("input").val(data);
// this.button.parent().hide();
//$(this).next("input").val(data);
},
onUploadError :function(file,data,response){
alert("上传图片失败,请重试");
}
});
});
</script>
<li>
<img id="picture1" src="http://"/>
<input type="file" name="uploadify" id="uploadify" />
<a class="delFtp" style="display:none;" href="javascript:void(0)" οnclick="DeleteImage(this)">删除图片</a>
<input id="uploader1_uploadedImageUrl" name="uploadedImageUrl" style="width:100px" value="" readonly />
</li>
基本上一个应用就完成了,下面说下我遇到的问题:
'uploader' : '<%=contextPath%>/scripts/uploadify',//后台处理的请求 <%=contextPath%>/scripts/uploadify
这个是设置文件接收的servlet,好像只能提交到servlet,不能提交到action(我用的struts2);并且在web.xml的设置里面
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
改成
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
(应为struts2的默认拦截器会拦截住,导致进入servlt后获取不到文件filelist为【】);
这个事解决方法1;
解决方法2就是在struts2拦截器之前添加一个过滤器,拦截上传图片的servlet:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpSession session = httpRequest.getSession(true);
chain.doFilter(new StrutsRequestWrapper((HttpServletRequest) httpRequest), response);
}
<filter>
<filter-name>uploadFilter</filter-name>
<filter-class>
com.eshore.cms.web.servlet.UploadFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>uploadFilter</filter-name>
<url-pattern>/ImgUploadServlet/*</url-pattern>
</filter-mapping>
因为struts拦截器不会拦截StrutsRequestWrapper类型的request。
在做的过程中我使用ie和火狐游览器,下面的包是我修改好的,可以用的。最主要的问题是在IE及火狐里面,如果上下拖动,上传按钮始终在原位
基于uploadify.css火狐使用正常,ie上传按钮不动,所以前面使用两套样式,js判断游览器,调用不同的css文件。还有个注意到的问题就是回调函数:
使用$(this)是获取不到对象的。像上面那样才可以。
下面贴出后台代码:
package com.eshore.cms.web.servlet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
public class ImgUploadServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = -212990395151027143L;
/**
* 实现文件/图片的上传
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//设置接收的编码格式
request.setCharacterEncoding("UTF-8");
Date date = new Date();//获取当前时间
SimpleDateFormat sdfFileName = new SimpleDateFormat("yyyyMMddHHmmss");
SimpleDateFormat sdfFolder = new SimpleDateFormat("yyMM");
String newfileName = sdfFileName.format(date);//文件名称
String fileRealPath = "";//文件存放真实地址
String fileRealResistPath = "";//文件存放真实相对路径
//名称 界面编码 必须 和request 保存一致..否则乱码
String name = request.getParameter("name");
// InputStream in = request.getInputStream();
String firstFileName="";
// 获得容器中上传文件夹所在的物理路径
String savePath = this.getServletConfig().getServletContext().getRealPath("/") + "uploads\\" + newfileName +"\\";
System.out.println("路径" + savePath+"; name:"+name);
File file = new File(savePath);
if (!file.isDirectory()) {
file.mkdirs();
}
try {
DiskFileItemFactory fac = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(fac);
upload.setHeaderEncoding("UTF-8");
// 获取多个上传文件
List fileList = upload.parseRequest(request);
// 遍历上传文件写入磁盘
Iterator it = fileList.iterator();
while (it.hasNext()) {
Object obit = it.next();
if(obit instanceof DiskFileItem){
System.out.println("xxxxxxxxxxxxx");
DiskFileItem item = (DiskFileItem) obit;
// 如果item是文件上传表单域
// 获得文件名及路径
String fileName = item.getName();
if (fileName != null) {
firstFileName=item.getName().substring(item.getName().lastIndexOf("\\")+1);
String formatName = firstFileName.substring(firstFileName.lastIndexOf("."));//获取文件后缀名
fileRealPath = savePath + newfileName+ formatName;//文件存放真实地址
BufferedInputStream in = new BufferedInputStream(item.getInputStream());// 获得文件输入流
BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(new File(fileRealPath)));// 获得文件输出流
Streams.copy(in, outStream, true);// 开始把文件写到你指定的上传文件夹
//上传成功,则插入数据库
if (new File(fileRealPath).exists()) {
//虚拟路径赋值
fileRealResistPath=sdfFolder.format(date)+"/"+fileRealPath.substring(fileRealPath.lastIndexOf("\\")+1);
//保存到数据库
System.out.println("保存到数据库:");
System.out.println("name:"+name);
System.out.println("虚拟路径:"+fileRealResistPath);
}
}
}
}
} catch (org.apache.commons.fileupload.FileUploadException ex) {
ex.printStackTrace();
System.out.println("没有上传文件");
return;
}
response.getWriter().write(fileRealPath);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}