Jsp页面实现文件上传下载类代码第1/2页
刚才和lp看完电影,把jsp页面抽出class调整了一下。最近总上经典,是感觉既然当了斑竹,就该留下点什么。lp这几天也半开玩笑半生气的说,一回来就上经典,就发帖,你干脆娶经典作lp得了。想想,这几天是有点夸张,以后放慢速度了。保持1星期1帖吧,那样也能多想写,多总结些。
发帖的初衷就是有时候看到有的朋友问的问题,似乎还没有走进java的门,希望这样的帖子,能对新手一点帮助,也就满足了。有时候随意的一段话,其实也是自己的一点经验,而有时候之所以絮絮叨叨,是想把问题说的清楚明白,让高手见笑了。因为在入门的时候,每一个小环节都可能郁闷半天,如果看到我的某段话,有所帮助的话,即使我说十句有一句有帮助,我也满足了。因为我在不停的说话。
现在把总结的jsp页面上传类发布出来。代码肯定还会存在问题,有bug的话,告诉我,我及时修正。
名称:jsp页面上传类
作者:sinner
mail:vogoals[at]hotmail.com
特点:
- 可以多文件上传;
- 返回上传后的文件名;
- form表单中的其他参数也可以得到。
先贴上传类,jspfileupload
package com.vogoal.util;
import java.io.bufferedoutputstream;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.text.simpledateformat;
import java.util.arraylist;
import java.util.date;
import java.util.hashtable;
import javax.servlet.servletinputstream;
import javax.servlet.http.httpservletrequest;
/*
* vogoalapi 1.0
* auther sinner@blueidea.com
* by vogoal.com
* mail: vogoals@hotmail.com
*/
/**
* jsp上传文件类
*
* @author sinner
* @version 1.0
*/
public class jspfileupload {
/** request对象 */
private httpservletrequest request = null;
/** 上传文件的路径 */
private string uploadpath = null;
/** 每次读取得字节的大小 */
private static int bufsize = 1024 * 8;
/** 存储参数的hashtable */
private hashtable paramht = new hasptable();
/** 存储上传的文件的文件名的arraylist */
private arraylist updfilearr = new arraylist();
/**
* 设定request对象。
*
* @param request
* httpservletrequest request对象
*/
public void setrequest(httpservletrequest request) {
this.request = request;
}
/**
* 设定文件上传路径。
*
* @param path
* 用户指定的文件的上传路径。
*/
public void setuploadpath(string path) {
this.uploadpath = path;
}
/**
* 文件上传处理主程序。�������b
*
* @return int 操作结果 0 文件操作成功;1 request对象不存在。 2 没有设定文件保存路径或者文件保存路径不正确;3
* 没有设定正确的enctype;4 文件操作异常。
*/
public int process() {
int status = 0;
// 文件上传前,对request对象,上传路径以及enctype进行check。
status = precheck();
// 出错的时候返回错误代码。
if (status != 0)
return status;
try {
// ��参数或者文件名�u��
string name = null;
// 参数的value
string value = null;
// 读取的流是否为文件的标志位
boolean fileflag = false;
// 要存储的文件。
file tmpfile = null;
// 上传的文件的名字
string fname = null;
fileoutputstream baos = null;
bufferedoutputstream bos = null;
// ��存储参数的hashtable
paramht = new hashtable();
updfilearr = new arraylist();
int rtnpos = 0;
byte[] buffs = new byte[bufsize * 8];
// �取得contenttype
string contenttype = request.getcontenttype();
int index = contenttype.indexof("boundary=");
string boundary = "--" + contenttype.substring(index + 9);
string endboundary = boundary + "--";
// �从request对象中取得流。
servletinputstream sis = request.getinputstream();
// 读取1行
while ((rtnpos = sis.readline(buffs, 0, buffs.length)) != -1) {
string strbuff = new string(buffs, 0, rtnpos);
// 读取1行数据�n��
if (strbuff.startswith(boundary)) {
if (name != null && name.trim().length() > 0) {
if (fileflag) {
bos.flush();
baos.close();
bos.close();
baos = null;
bos = null;
updfilearr.add(fname);
} else {
object obj = paramht.get(name);
arraylist al = new arraylist();
if (obj != null) {
al = (arraylist) obj;
}
al.add(value);
system.out.println(value);
paramht.put(name, al);
}
}
name = new string();
value = new string();
fileflag = false;
fname = new string();
rtnpos = sis.readline(buffs, 0, buffs.length);
if (rtnpos != -1) {
strbuff = new string(buffs, 0, rtnpos);
if (strbuff.tolowercase().startswith(
"content-disposition: form-data; ")) {
int nindex = strbuff.tolowercase().indexof(
"name=\"");
int nlastindex = strbuff.tolowercase().indexof(
"\"", nindex + 6);
name = strbuff.substring(nindex + 6, nlastindex);
}
int findex = strbuff.tolowercase().indexof(
"filename=\"");
if (findex != -1) {
fileflag = true;
int flastindex = strbuff.tolowercase().indexof(
"\"", findex + 10);
fname = strbuff.substring(findex + 10, flastindex);
fname = getfilename(fname);
if (fname == null || fname.trim().length() == 0) {
fileflag = false;
sis.readline(buffs, 0, buffs.length);
sis.readline(buffs, 0, buffs.length);
sis.readline(buffs, 0, buffs.length);
continue;
}else{
fname = getfilenamebytime(fname);
sis.readline(buffs, 0, buffs.length);
sis.readline(buffs, 0, buffs.length);
}
}
}
} else if (strbuff.startswith(endboundary)) {
if (name != null && name.trim().length() > 0) {
if (fileflag) {
bos.flush();
baos.close();
bos.close();
baos = null;
bos = null;
updfilearr.add(fname);
} else {
object obj = paramht.get(name);
arraylist al = new arraylist();
if (obj != null) {
al = (arraylist) obj;
}
al.add(value);
paramht.put(name, al);
}
}
} else {
if (fileflag) {
if (baos == null && bos == null) {
tmpfile = new file(uploadpath + fname);
baos = new fileoutputstream(tmpfile);
bos = new bufferedoutputstream(baos);
}
bos.write(buffs, 0, rtnpos);
baos.flush();
} else {
system.out.println("test :" + value + "--" + strbuff);
value = value + strbuff;
}
}
}
} catch (ioexception e) {
status = 4;
}
return status;
}
private int precheck() {
int errcode = 0;
if ( request == null )
return 1;
if ( uploadpath == null || uploadpath.trim().length() == 0 )
return 2;
else{
file tmpf = new file(uploadpath);
if (!tmpf.exists())
return 2;
}
string contenttype = request.getcontenttype();
if ( contenttype.indexof("multipart/form-data") == -1 )
return 3;
return errcode;
}
public string getparameter(string name){
string value = "";
if ( name == null || name.trim().length() == 0 )
return value;
value = (paramht.get(name) == null)?"":(string)((arraylist)paramht.get(name)).get(0);
return value;
}
public string[] getparameters(string name){
if ( name == null || name.trim().length() == 0 )
return null;
if ( paramht.get(name) == null )
return null;
arraylist al = (arraylist)paramht.get(name);
string[] strarr = new string[al.size()];
for ( int i=0;i<al.size();i++ )
strarr[i] = (string)al.get(i);
return strarr;
}
public int getupdfilesize(){
return updfilearr.size();
}
public string[] getupdfilenames(){
string[] strarr = new string[updfilearr.size()];
for ( int i=0;i<updfilearr.size();i++ )
strarr[i] = (string)updfilearr.get(i);
return strarr;
}
private string getfilename(string input){
int findex = input.lastindexof("\\");
if (findex == -1) {
findex = input.lastindexof("/");
if (findex == -1) {
return input;
}
}
input = input.substring(findex + 1);
return input;
}
private string getfilenamebytime(string input){
int index = input.indexof(".");
date dt = new date();
simpledateformat sdf = new simpledateformat("yyyymmddhhmmsssss");
return input.substring(0,index) + sdf.format(dt) + input.substring(index);
}
}
说明:
这个类基本解决了上一贴的上一贴说的存在的bug和不足。主要做了如下修正。
- 用户可以设定文件上传的路径,这里没有用request对象的getrealpath方法来取得相对路径,而是用了绝对路径。是一个小败笔。因为有时候用户只是得到服务器的一个应用,而不知道整个服务器的路径。但是既然getrealpath自己可以得到,用户自己取得也可以。
- 在文件上传处理的时候,预先进行了check,把一些可能出现的造成上传失败的情况拍查掉。避免该类出现不该出现的异常。
- 捕获了io异常,避免文件上传的时候出现异常时程序的不友好表现
- 提供了方法返回form表单中其他参数的取得,模拟了httpservletrequest对象的getparameter和getparameters方法(后面这个方法是叫这个名字么-_-b),取得parameter的名称的方法没有提供,是个小缺陷。
- 提供了方法返回上传的文件的件数和上传的文件名,方便用户作其他操作。
现在介绍下jsp页面中如何用这个类实现上传。
首先,要把这个类编译后的class文件拷贝到web-inf/classes/目录下。注意保持package的结构。
在jsp页面中引用这个类
< import="com.vogoal.util.jspfileupload"%> <%
//初始化
jspfileupload jfu = new jspfileupload();
//设定request对象
jfu.setrequest(request);
//设定上传的文件路径
jfu.setuploadpath("c:\\");
//上传处理
int rtn = jfu.process();
//取得form中其他input控件参数的值
string username = jfu.getparameter("username");
//如果对应同一个参数有多个input控件,返回数组
string[] usernamearr = jfu.getparameters("username");
//取得上传的文件的名字
string[] filearr = jfu.getupdfilenames();
//取得上传文件的个数,这个方法有点鸡肋
int filenumber = jfu.getupdfilesize();
//下面的是测试输出的代码。
// out.println("parameter:" + username);
// out.println("parameter size:" + usernamearr.length);
// out.println("filearr size:" + filearr.length);
// if (filearr.length > 0)
// out.println("filearr 0:" + filearr[0]);
%>
使用的时候的注意事项:
- 一定要设定request对象。
- 一定要设定正确的上传路径。
- 执行完了之后才可以得到其他参数,因为执行了之后这些参数才被分析。
1,2两点如果没有做到的话,process方法执行的时候汇报错。
各个用户可用的方法及说明:
设定requet对象。
public void setrequest(httpservletrequest request)
设定文件上传的路径。
public void setuploadpath(string path)
文件上传处理主程序。
@return int 操作结果 0 文件操作成功;1 request对象不存在。 2 没有设定文件保存路径或者文件保存路径不正确;3
没有设定正确的enctype;4 文件操作异常。
public int process()
根据name取得form表单中其他传递的参数的值(多个的话返回其中一个)
public string getparameter(string name)
根据name取得form表单中其他传递的参数的值(返回数组,可有多个)
public string[] getparameters(string name)
取得上传成功文件的个数
public int getupdfilesize()
取得上传的文件名对应的数组。
public string[] getupdfilenames()
注意process方法地返回值,在不是0的情况下操作失败。
以下提供测试类以及测试页面(见附件):
hellopostfile.html
hellopostfile.jsp
写在jsp中的代码的测试文件。
hellopostfilewithclass.html
hellopostfilewithclass.jsp
抽出class后的测试文件。
src在
web-inf/src/
class在
web-inf/classes/
另:
由于这个文件被我在中文日文系统下编辑过,注释出现乱码,所以大部分都删掉了,见谅。