当前idle状态!捣腾了一个文件上传功能,小温故了一把java/servlet上传的原理。

上传代码未用struts2,读取进度时才用了一下,本身struts2也把下面2个开源包'集成'进去了!代码都是在网上cp的,自己拼凑,加了一些注释。

当然,如果页面上没有Form表单(甚至是也未用struts2框架),就无法以表单(mutilpart/form-data格式)提交到后台,这时候可以借用第三方控件,如:flash插件或 (c++ ocx)控件等,辅助模仿form表单提交到jsp页面,再用jsp接收输入流,达到上传文件的目的!

需要的jar:commons-fileupload-x.x.x.jar 和 commons-io-x.x.x.jar

首先是前端页面代码,(extjs3.3.1)


var m =0 ;
var _interval;
Ext.onReady(function() {
var formPanel = new Ext.form.FormPanel({
labelWidth:80,
id:'formPanel',
bodyStyle:'padding:5 0 0 0 ',
height:515,
width:200,
frame:true,
fileUpload:true,
items:[new Ext.form.TextField({
id:'excelUpload',
anchor:'90%',
height:30,
width:350,
name:'file',
inputType:'file',
fieldLabel:'文件选择'
})
]
});
var upLoadFile = new Ext.Toolbar.Button({
text:'上传',
listeners:{
'click': uploadFiles
}
});
new Ext.Window({
title:'上传文件',
width:400,
height:140,
minWidth:400,
id:'uploadWin',
minHeight:140,
layout:'fit',
plain:true,
bodyStyle:'padding:5px;',
buttonAlign:'center',
items:formPanel,
buttons:[upLoadFile]
}).show();
});
function uploadFiles(t){
var excelName = Ext.getCmp('excelUpload').getRawValue();// 上传文件名称的路径
if (excelName == ""){
Ext.Msg.alert("提示","请选择需要上传的文件!");
return;
}else {
var array = new Array();
array = excelName.split("\\");
var length = array.length;
var fileName = "";
var index = 0;
for (index = 0; index < length; index++) {
if (fileName == "") {
fileName = array[index];
} else {
fileName = fileName + "/" + array[index];
}
}
_interval = setInterval("showRequest()", 100);
Ext.getCmp("formPanel").getForm().submit({
url:'servlet/fileUpload',
method:'POST',
success:function(form, action, o) {
Ext.MessageBox.alert("提示信息",action.result.message);
Ext.getCmp("uploadWin").setTitle("上传文件");
},
failure : function(form, action) {
Ext.MessageBox.alert("提示信息","请求失败,文件上传失败");
}
});
}
}
function showRequest(){
Ext.Ajax.request( {
url : 'loginAction/getUploadPrcent.action',
method : 'post',
success: function(data, options){
Ext.getCmp("uploadWin").setTitle("上传文件:已经写入("+data.responseText+")");
if(data.responseText =='100%'){
clearInterval(_interval);
Ext.getCmp("uploadWin").setTitle("上传文件:写入完成,请稍等...");
return;
}
m++ ;
}
});
}
再贴监听方法:
public class UploadProgressListener implements ProgressListener {//要继承ProgressListener
private double megaBytes = -1;
private HttpSession session;
public UploadProgressListener(HttpServletRequest request) {
session=request.getSession();
}
public void update(long pBytesRead, long pContentLength, int pItems) {
double mBytes = pBytesRead / 1000000;
double total=pContentLength/1000000;
if (megaBytes == mBytes) {
return;
}
System.out.println("total====>"+total);
System.out.println("mBytes====>"+mBytes);
megaBytes = mBytes;
System.out.println("megaBytes====>"+megaBytes);
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength
+ " bytes have been read.");
double read=(mBytes/total);
NumberFormat nf=NumberFormat.getPercentInstance();
System.out.println("生成读取的百分比 并放入session中===>"+nf.format(read));//生成读取的百分比 并放入session中
session.setAttribute("readPrcnt", nf.format(read));
}
}
}
再贴:上传dopost()方法:
public class fileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
public fileUpload() {
super();
}
public void destroy() {
super.destroy();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
//文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性
boolean isMultipart = ServletFileUpload.isMultipartContent(request); //判断上传表单是否为multipart/form-data类型
if (isMultipart) {
// 创建磁盘工厂,利用构造器实现内存数据储存量和临时储存路径
DiskFileItemFactory factory=new DiskFileItemFactory();
factory.setSizeThreshold(4096);
// 设置文件临时存储路径
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
// 产生一新的文件上传处理程式
ServletFileUpload upload = new ServletFileUpload(factory);
ProgressListener progressListener = new UploadProgressListener(request);
request.getSession().setAttribute("progress", progressListener);
upload.setProgressListener(progressListener);
//文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性
upload.setSizeMax(1024 * 1024 * 100); // 设置允许用户上传文件大小,单位:字节
FileOutputStream out = null ;
InputStream in = null;
// 得到所有的表单域,它们目前都被当作FileItem
try {
// 解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。
//upload对象是使用DiskFileItemFactory 对象创建的ServletFileUpload对象,并设置了临时文件路径 传输文件大小等等。
List list = upload.parseRequest(request);
Iterator it=list.iterator();
while(it.hasNext())
{
FileItem item=(FileItem)it.next();// 每一个item就代表一个表单输出项
String filename = item.getName();
if(item.getName() != null && !item.isFormField()){
// 得到上传文件的名称,并截取
String savePath = this.getServletContext().getRealPath("/upload");//在WebRoot下面建了一个文件夹
String extensionName = filename.substring(filename.lastIndexOf(".") + 1);//获取文件后缀名
out=new FileOutputStream(savePath+"\\"+ UUID.randomUUID()+"."+extensionName);
in = item.getInputStream();
byte buffer[] = new byte[1024];
int len = 0;
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
response.setContentType("text/html;charset=GB2312");
response.getWriter().print("{'success':true,'message':'上传成功'}");
}
item.delete();
}
}
catch (FileUploadException e) {
e.printStackTrace();
} finally{
try{
response.getWriter().close();
in.close();
out.close();
}catch(Exception ex){
System.out.println(ex);
}
}
}
}
public void init() throws ServletException {
// Put your code here
}
}
web.xml servlet配置:
fileUpload
upload.fileUpload
fileUpload
/servlet/fileUpload