本来在介绍 用TOMCAT作简单的jsp web开发 的帖子中已经提过,但是有些筒子不喜欢看又臭又硬的文字,所以可能不会注意到,就重新开帖发出来。请其他管理见谅。
Webjx.Com
顺便打算今后多写几个util函数,能用上的就用下。代码开发的过程见 用TOMCAT作简单的jsp web开发
网页教学网
刚才和lp看完电影,把jsp页面抽出class调整了一下。最近总上经典,是感觉既然当了斑竹,就该留下点什么。lp这几天也半开玩笑半生气的说,一回来就上经典,就发帖,你干脆娶经典作lp得了。想想,这几天是有点夸张,以后放慢速度了。保持1星期1帖吧,那样也能多想写,多总结些。
发帖的初衷就是有时候看到有的朋友问的问题,似乎还没有走进java的门,希望这样的帖子,能对新手一点帮助,也就满足了。有时候随意的一段话,其实也是自己的一点经验,而有时候之所以絮絮叨叨,是想把问题说的清楚明白,让高手见笑了。因为在入门的时候,每一个小环节都可能郁闷半天,如果看到我的某段话,有所帮助的话,即使我说十句有一句有帮助,我也满足了。因为我在不停的说话。
Webjx.Com
现在把总结的jsp页面上传类发布出来。代码肯定还会存在问题,有bug的话,告诉我,我及时修正。 网页教学网
名称:jsp页面上传类
作者:SinNeR
Mail:vogoals[at]hotmail.com
Webjx.Com
特点:
Webjx.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;
Webjx.Com
/** 存储参数的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
* 用户指定的文件的上传路径。
Webjx.Com
*/
public void setUploadPath(String path) {
this.uploadPath = path;
}
/**
* 文件上传处理主程序。鼴
*
* @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 {
// 参数或者文件名齯
String name = null;
// 参数的value
String value = null;
// 读取的流是否为文件的标志位
boolean fileFlag = false;
// 要存储的文件。
File tmpFile = null;
Webjx.Com
// 上传的文件的名字
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];
// 〉肅ontentType 网页教学网
String contentType = request.getContentType();
int index = contentType.indexOf("boundary=");
String boundary = "--" + contentType.substring(index + 9);
String endBoundary = boundary + "--";
// 觬equest对象中取得流。
ServletInputStream sis = request.getInputStream();
// 读取1行
while ((rtnPos = sis.readLine(buffs, 0, buffs.length)) != -1) {
String strBuff = new String(buffs, 0, rtnPos);
Webjx.Com
// 读取1行数据齨
if (strBuff.startsWith(boundary)) {
if (name != null && name.trim().length() > 0) {
if (fileFlag) {
bos.flush();
baos.close();
bos.close();
Webjx.Com
baos = null;
bos = null;
updFileArr.add(fName);
} else {
Object obj = paramHt.get(name);
ArrayList al = new ArrayList();
Webjx.Com
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( Webjx.Com
"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); Webjx.Com
}
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{ Webjx.Com
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 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 strArr[i] = (String)updFileArr.get(i); return strArr; } private String getFileName(String input){ int fIndex = input.lastIndexOf("\\"); Webjx.Com 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"); Webjx.Com return input.substring(0,index) + sdf.format(dt) + input.substring(index); } } 网页教学网 说明: 这个类基本解决了上一贴的上一贴说的存在的bug和不足。主要做了如下修正。 Webjx.Com 用户可以设定文件上传的路径,这里没有用request对象的getRealPath方法来取得相对路径,而是用了绝对路径。是一个小败笔。因为有时候用户只是得到服务器的一个应用,而不知道整个服务器的路径。但是既然getRealPath自己可以得到,用户自己取得也可以。 在文件上传处理的时候,预先进行了check,把一些可能出现的造成上传失败的情况拍查掉。避免该类出现不该出现的异常。 捕获了IO异常,避免文件上传的时候出现异常时程序的不友好表现 提供了方法返回form表单中其他参数的取得,模拟了HttpServletRequest对象的getParameter和getParameters方法(后面这个方法是叫这个名字么-_-b),取得Parameter的名称的方法没有提供,是个小缺陷。 提供了方法返回上传的文件的件数和上传的文件名,方便用户作其他操作。 现在介绍下JSP页面中如何用这个类实现上传。 首先,要把这个类编译后的class文件拷贝到WEB-INF/classes/目录下。注意保持package的结构。 Webjx.Com 在jsp页面中引用这个类 Webjx.Com <%@page 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); Webjx.Com // 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方法执行的时候汇报错。 各个用户可用的方法及说明: Webjx.Com 设定requet对象。 public void setRequest(HttpServletRequest request) 设定文件上传的路径。 public void setUploadPath(String path) 文件上传处理主程序。 @return int 操作结果 0 文件操作成功;1 request对象不存在。 2 没有设定文件保存路径或者文件保存路径不正确;3 没有设定正确的enctype;4 文件操作异常。 public int process() Webjx.Com 根据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/ 另: 由于这个文件被我在中文日文系统下编辑过,注释出现乱码,所以大部分都删掉了,见谅。 Webjx.Com 下载:WEB-INF.zip JSP文件下载类整理完成。可以在JSP页面中实现简单的下载,支持文件打包下载功能。支持将字符串或者流生成文件提供下载的功能。但是也有一些缺点。现把这个类的基本介绍总结如下。 名称:jsp页面下载类 作者:SinNeR Mail:vogoals[at]hotmail.com 特点及功能介绍: Webjx.Com 支持单文件下载。支持多文件zip压缩下载。多文件zip压缩可在服务器保留或者删除副本。支持将特定的字符串或者byte数组以指定的文件名提供下载。 在下载过程中需要提供response对象。并且选择下载形式。 下载处理前先进行check,避免出现错误。 下载处理过程中出错时,会报告错误信息。 日文系统下文件名是中文时出现乱码问题。 处理前需要进行相对繁琐的设定。 现介绍下使用者可见的方法的功能。 设定实现下载必须的response对象。 public void setResponse(HttpServletResponse response) 网页教学网 设定下载方式:0 为普通单文件下载。 1 为多文件压缩成zip包下载。 2 为将指定的字符串等拼接成文件内容提供给用户下载。 public void setDownType(int fileType) Webjx.Com 设定下载时显示给用的文件名。 public void setDisFileName(String fileName) 网页教学网 压缩文件下载时,设定压缩文件暂时保存的路径(路径为绝对路径) public void setZipFilePath( String path ) 压缩文件下载时,设定服务器端生成的压缩文件是否删除。True 删除;false 保留。 public void setZipDelFlag(boolean b) 压缩文件下载时,设定要压缩的文件的文件路径(路径为绝对路径) public void setZipFileNames(String[] fileNames) 单文件下载时,设定下载文件的路径(绝对路径) public void setDownFileName(String fileName) Webjx.Com 将字符串生成文件内容模拟下载时,设定文件的内容。参数为字符串(可多次调用) public int setFileContent(String fileContent) 将字符串生成文件内容模拟下载时,设定文件的内容。参数为byte数组(可多次调用) 返回值:0 操作正常; 9 出现IO异常。 public int setFileContent(byte[] fileContent) 将字符串生成文件内容模拟下载时,调用此方法结束文件内容设定。 返回值:0 操作正常; 9 出现IO异常。 public int setFileContentEnd() 主处理函数。 返回值: 0 处理正常;1 未设定response对象。 2 未设定文件下载方式。 3 未设定要显示的文件名。 4 未设定要下载的文件路径,或者设定的下载的文件路径不存在。 9 IO异常。 public int process() 现在介绍不同下载模式下的简单流程: 单文件下载流程: //实例初始化 JspFileDownload jfd = new JspFileDownload(); //设定response对象 jfd.setResponse(response); //设定文件下载模式 0 单文件下载。 jfd.setDownType(0); //设定显示的文件名 xxxx.xxx jfd.setDisFileName(filename); //设定要下载的文件的路径,绝对路径 jfd.setDownFileName(filePath); //主处理函数。注意处理返回值。 int result = jfd.process(); 网页教学网 多文件压缩成ZIP文件下载: //实例初始化 JspFileDownload jfd = new JspFileDownload(); //设定response对象。 jfd.setResponse(response); //设定下载模式 1 多文件压缩成ZIP文件下载。 jfd.setDownType(1); //设定显示的文件名 jfd.setDisFileName(filename); //设定要下载的文件的路径(数组,绝对路径) jfd.setZipFileNames(fileNames); //设定服务器端生成的zip文件是否保留。 true 删除 false 保留,默认为false jfd.setZipDelFlag(true); //设定zip文件暂时保存的路径 (是文件夹) jfd.setZipFilePath(zipfolder); //主处理函数 注意返回值 Int result = jfd.process(); 网页教学网 将字符串生成为文件内容,模拟文件下载: //实例初始化 JspFileDownload jfd = new JspFileDownload(); //设定response对象。 jfd.setResponse(response); //设定下载模式 2 将字符串作为文件内容,实现文件下载。 jfd.setDownType(2); //设定文件显示的名称。 jfd.setDisFileName(request.getParameter("filename")); //主处理函数,下载前check,注意返回值 out.print(jfd.process()); //设定要写入文件的内容,参数可为字符串或者byte数组。可多次调用。 jfd.setFileContent(request.getParameter("name")); //文件内容设定完了,调用函数。 jfd.setFileContentEnd(); 以上就是简单的使用介绍。下面贴出主处理类的代码。由于在日文系统下编辑的文件。注释只能写英文,英文太差-_-b。多包涵。 Webjx.Com package com.vogoal.util; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; /* * vogoalAPI 1.0 * Auther SinNeR@blueidea.com * by vogoal.com * mail: vogoals@hotmail.com */ /** * JSP FILE DOWNLOAD SUPPORT * * @author SinNeR * @version 1.0 */ public class JspFileDownload { /** request object */ private HttpServletResponse response = null; /** file type: -1 un-setting; 0 normal file; 1 zip file ;2 stream*/ private int fileType = -1; /** file name to be displayed */ private String disFileName = null; /** zip file path */ private String zipFilePath = null; /** file to be zipped */ private String[] zipFileNames = null; private boolean zipDelFlag = false; /** file to be downloaded */ private String downFileName = null; /** error code 0 */ private static final int PROCESS_OK = 0; /** error code 1 */ private static final int RESPONSE_IS_NULL = 1; /** error code 2 */ private static final int UNSET_DOWNLOADTYPE = 2; /** error code 3 */ private static final int UNSET_DIS_FILE_NAME = 3; Webjx.Com /** error code 4 */ private static final int UNSET_DOWN_FILE_NAME = 4; /** error code 9 */ private static final int IO_EXCEPTION = 9; /** * set response object * @param response response Object */ public void setResponse(HttpServletResponse response){ this.response = response; } /** * set file type 0 normal file; 1 zip file ;2 stream * @param fileType */ public void setDownType(int fileType){ this.fileType = fileType; } /** * set display file name * @param fileName */ public void setDisFileName(String fileName){ this.disFileName = fileName; } /** * set zip file path * @param fileNames */ public void setZipFilePath( String path ){ this.zipFilePath = path; } public void setZipDelFlag(boolean b){ this.zipDelFlag = b; } /** * set zip file names * @param fileNames Webjx.Com */ public void setZipFileNames(String[] fileNames){ this.zipFileNames = fileNames; } /** * set download file name * @param fileName */ public void setDownFileName(String fileName){ this.downFileName = fileName; } /** * set file content * @param fileContent */ public int setFileContent(String fileContent){ try{ byte[] buffs = fileContent.getBytes("UTF-8"); Webjx.Com response.getOutputStream().write(buffs); }catch(IOException e){ return IO_EXCEPTION; } return PROCESS_OK; } /** * set file content * @param fileContent */ public int setFileContent(byte[] fileContent){ try{ response.getOutputStream().write(fileContent); }catch(IOException e){ return IO_EXCEPTION; } 网页教学网 return PROCESS_OK; } /** * set file content end * */ public int setFileContentEnd(){ try{ response.getOutputStream().close(); }catch(IOException e){ return IO_EXCEPTION; } return PROCESS_OK; } /** * main process * @return */ public int process(){ int status = PROCESS_OK; Webjx.Com status = preCheck(); if ( status != PROCESS_OK ) return status; String fileName = disFileName; response.setContentType("APPLICATION/OCTET-STREAM"); response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\""); int BUFSIZE = 1024 * 8; int rtnPos = 0; byte[] buffs = new byte[ BUFSIZE ]; 网页教学网 FileInputStream inStream = null; ZipOutputStream zos = null; InputStream is = null; String filepath = null; try{ if ( fileType == 0 || fileType == 1){ if ( fileType == 0 ){ filepath = downFileName; }else{ filepath = zipFilePath + fileName; String[] fileToZip = zipFileNames; zos=new ZipOutputStream(new FileOutputStream(filepath)); ZipEntry ze=null; byte[] buf=new byte[BUFSIZE]; int readLen=0; for (int i= 0;i File f= new File(fileToZip[i]); ze=new ZipEntry(f.getName()); ze.setSize(f.length()); ze.setTime(f.lastModified()); zos.putNextEntry(ze); is=new BufferedInputStream(new FileInputStream(f)); while ((readLen=is.read(buf, 0, BUFSIZE))!=-1) { zos.write(buf, 0, readLen); } is.close(); } zos.close(); } inStream =new FileInputStream(filepath); while((rtnPos=inStream.read(buffs)) >0) response.getOutputStream().write(buffs,0,rtnPos); response.getOutputStream().close(); inStream.close(); } if ( zipDelFlag ){ File fToDel = new File(filepath); Webjx.Com fToDel.delete(); } }catch(IOException e){ return IO_EXCEPTION; }finally{ try{ if ( inStream != null ){ inStream.close(); inStream = null; } if ( zos != null ){ 网页教学网 zos.close(); zos = null; } if ( is != null ){ is.close(); is = null; } }catch (IOException e){ } } Webjx.Com return status; } /** * pre check. * @return */ private int preCheck(){ if ( response == null ) return RESPONSE_IS_NULL; if ( disFileName == null || disFileName.trim().length() == 0 ) return UNSET_DIS_FILE_NAME; if ( fileType == -1 ) return UNSET_DOWNLOADTYPE; else if ( fileType == 0 ){ if ( downFileName == null || downFileName.trim().length() == 0 ) return UNSET_DOWN_FILE_NAME; else{ if ( !isFile( downFileName ) ) return UNSET_DOWN_FILE_NAME; } }else if ( fileType == 1 ){ if ( zipFilePath == null || zipFilePath.length() == 0 ) return UNSET_DOWN_FILE_NAME; else{ if ( !isDirect(zipFilePath) ) return UNSET_DOWN_FILE_NAME; } if ( zipFileNames == null || zipFileNames.length == 0 ) return UNSET_DOWN_FILE_NAME; else{ for ( int i=0;i if ( zipFileNames[i] == null || zipFileNames[i].trim().length() == 0 ) return UNSET_DOWN_FILE_NAME; else{ if ( !isFile( zipFileNames[i] ) ) return UNSET_DOWN_FILE_NAME; } } } }else if ( fileType == 2 ){ Webjx.Com //doing nothing }else{ return UNSET_DOWNLOADTYPE; } return PROCESS_OK; } private boolean isFile(String fileName){ File f = new File(fileName); if (!f.exists() || !f.isFile()) return false; return true; } private boolean isDirect(String filePath){ File f = new File(filePath); if (!f.exists() || !f.isDirectory()) return false; return true; } } 至此,jsp页面文件下载介绍完成。 使用的时候,把这个类生成的class文件拷贝到WEB-INF/classes下。(注意保持包的路径) 然后在使用的页面import进这个class即可。 <%@ page contentType="text/html;charset=GBK"%> Webjx.Com 注意: 可能存在编码方式的问题,如果出现或者有别的bug请联系我,我来debug。 Webjx.Com 附件为这个类的source以及测试程序。 附件说明: 单文件下载测试程序 请求页面:downloadSimpleFile.html 下载功能实现页面:downloadSimpleFile.jsp 多文件压缩成zip文件下载的测试程序 请求页面:downloadZipFile.html 下载功能实现页面:downloadZipFile.jsp 字符串生成文件内容模拟文件下载的测试程序。 请求页面:downloadStreamFile.html 下载功能实现页面:downloadStreamFile.jsp Source及class文件。 Source WEB-INF/src/com/vogoal/util/ JspFileDownload.java Class文件WEB-INF/classes/com/vogoal/util/ JspFileDownload.class 下载:jspDownloadClass.zip 以上文件为SinNeR劳动成果,归blueidea所有,转载请注明出处。 Webjx.Com

