对原来的Upload又重新用JDK1.5重写了一次.因为JDK已经发布1.6了,如果你还在用1.4,那你只好自己
根据我的思路翻译了.这个Bean最初是我在2002年写的(在此之前的文章当然是别人的原创),然后网上就出了
很多修改一些变量名,方法名或类名的各种版本,当然"版权"也就成了这些修改者的了.2002年我的原文在cnJBB
上,可以在那儿搜索到.
对这个Bean使用是非常简单.下面提供测试的代码.但愿意不再有人再问这个问题了.
html内容:
<form method="POST" action="http://localhost/servlet/debug.ServletTest?ccc=1&ccc=2" enctype="multipart/form-data">
<input type="text" name="aaa"><br/>
<input type="checkbox" name="bbb">b1<br/>
<input type="checkbox" name="bbb">b2<br/>
<input type="checkbox" name="bbb">b3<br/>
<br/>
<input type="file" name="filefeild"><br/>
<input type="file" name="filefeild"><br/>
<br/>
<input type="submit">
</form>
调用Bean的Servlet为:
public void service(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
Upload up = new Upload();
up.init(request);
//在此之前request只能获取header,不能有获取实体的调用,即不能getInputStream或getParameter
up.setSaveDir("d:/test/");
up.setTagFileName("test.dat");//只对第一个文件起作用
//这里可以设置其经属性.
up.uploadFile();
String aaa = up.getParameter("aaa");
String[] bbb = up.getParameterValues("bbb");
String[] ccc = up.getParameterValues("ccc");
String[] fileName = up.getFileName();
up.clear();
System.out.println("aaa="+aaa);
for(int i=0;i<bbb.length;i++)
System.out.println("bbb="+bbb[i]);
for(int i=0;i<ccc.length;i++)
System.out.println("ccc="+ccc[i]);
for(int i=0;i<fileName.length;i++)
System.out.println(fileName[i]+":"+new File("d:/test/"+fileName[i]).exists());
out.close();
}
这个调用打印的结果为:
aaa=qqqq
bbb=on
bbb=on
bbb=on
ccc=1
ccc=2
test.dat.exe:true
daemon344.exe:true
下面是Upload.java:
package debug;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.regex.*;
public class Upload {
private String saveDir = "."; //要保存文件的路径
private String charset = "UTF-8"; //字符集
private HashMap<String,ArrayList> parameter = new HashMap(); //存放参数名和值的数据结构
private HttpServletRequest request; //用于传入请求对象的实例
private String boundary = ""; //内存数据的分隔符
private int len = 0; //每次从内在中实际读到的字节长度
private String queryString;
private int count; //上载的文件总数
private String[] fileName; //上载的文件名数组
private long maxFileSize = 1024 * 1024 * 10; //最大文件上载字节;
private String tagFileName = "";
public final void init(HttpServletRequest request) throws ServletException {
this.request = request;
Matcher m = Pattern.compile("boundary=([\\s\\S]+)").matcher(request.getContentType());
if(m.find())
this.boundary = m.group(1);
this.queryString = request.getQueryString();
}
/***
* 用于得到指定字段的参数值,重写request.getParameter(String s)
*/
public String getParameter(String key) {
if (parameter.isEmpty()) {
return null;
}
return (String) ((ArrayList)parameter.get(key)).get(0);
}
/***
* 用于得到指定同名字段的参数数组,重写request.getParameterValues(String s)
*/
public String[] getParameterValues(String key) {
if (parameter.isEmpty()) return null;
ArrayList al = parameter.get(key);
return (String[])al.toArray(new String[al.size()]);
}
public String getQueryString() {
return queryString;
}
public int getCount() {
return count;
}
public String[] getFileName() {
return fileName;
}
public void setMaxFileSize(long size) {
maxFileSize = size;
}
public void setTagFileName(String filename) {
tagFileName = filename;
}
/***
* 设置上载文件要保存的路径
*/
public void setSaveDir(String saveDir) {
this.saveDir = saveDir;
File testdir = new File(saveDir); //为了保证目录存在,如果没有则新建该目录
if (!testdir.exists()) testdir.mkdirs();
}
/***
* 设置字符集
*/
public void setCharset(String charset) {
this.charset = charset;
}
/***
* 用户调用的上载方法
*/
public boolean uploadFile() throws ServletException, IOException {
setCharset(request.getCharacterEncoding());
return uploadFile(request.getInputStream());
}
/***
* 清理参数占用的数据结构资源.
*/
public void clear(){
Iterator i = this.parameter.values().iterator();
while(i.hasNext()){
ArrayList al = (ArrayList) i.next();
al.clear();
}
parameter.clear();
}
/***
* 取得InputStream中数据的主方法
*/
private boolean uploadFile(ServletInputStream in) throws
ServletException, IOException {
String line = null;
byte[] buffer = new byte[256];
byte[] lastbuffer = null;
int lastlen = 0;
ArrayList<String> tmpFileName = new ArrayList();
while ( (line = readLine(buffer, in, charset)) != null) {
if (line.toLowerCase().startsWith("content-disposition: form-data;")) {
if (line.indexOf("filename=") != -1) { //如果一段分界符内的描述中有filename=,说明是文件的编码内容
String fName = getFileName(line);
if (fName.trim().length() == 0) {
continue;
}
if (count == 0 && tagFileName.length() != 0) {
//对第一个文件扩展名进行特殊处理.
String ext = fName.substring( (fName.lastIndexOf(".") + 1));
fName = tagFileName + "." + ext;
}
tmpFileName.add(fName);
count++;
while ( (line = readLine(buffer, in, charset)) != null) {
if (line.length() <= 2) {
break;
}
}
//System.out.println(fName);
File f = new File(saveDir, fName);
FileOutputStream out = new FileOutputStream(f);
long size = 0l;
lastbuffer = new byte[0];
lastlen = 0;
size += len;
if (size >= maxFileSize) {
throw new IOException("文件已超过最大值:" + this.maxFileSize + "字节");
}
while ( (line = readLine(buffer, in, null)) != null) {
if (line.indexOf(boundary) != -1) {
out.write(lastbuffer, 0, lastlen - 2);
break;
}
out.write(lastbuffer, 0, lastlen);
lastbuffer = arraycopy(buffer, 0, len);
lastlen = len;
}
out.close();
}
else { //否则是字段编码的内容
String key = getKey(line);
StringBuilder value = new StringBuilder();
while ( (line = readLine(buffer, in, charset)) != null) {
if (line.length() <= 2) {
break;
}
}
while ( (line = readLine(buffer, in, charset)) != null) {
if (line.indexOf(boundary) != -1) {
break;
}
value.append(line);
}
put(key.trim(), value.toString().trim(), parameter);
}
}
}
if (queryString != null) {
String[] each = split(queryString, "&");
for (int k = 0; k < each.length; k++) {
String[] nv = split(each[k], "=");
if (nv.length == 2) {
put(nv[0].trim(), nv[1].trim(), parameter);
}
}
}
fileName = tmpFileName.toArray(new String[tmpFileName.size()]);
tmpFileName.clear();
if (fileName.length == 0) {
return false; //如果fileName数据为空说明没有上载任何文件
}
return true;
}
/***
* 可以将多个value压入一上同名KEY中.
*/
private void put(String key, String value, HashMap<String,ArrayList> hm) {
ArrayList al = (hm.containsKey(key))?hm.get(key):new ArrayList();
al.add(value);
hm.put(key,al);
}
/***
* 从输入流中读取一行数据到byte[]中同时返回该数据的String表示以例分析
*/
private String readLine(byte[] lineBytes,ServletInputStream in, String charset) {
try {
len = in.readLine(lineBytes, 0, lineBytes.length);
if (len == -1) return null;
if (charset == null) return new String(lineBytes, 0, len);
return new String(lineBytes, 0, len, charset);
}
catch (Exception ex) {
return null;
}
}
/***
* 从描述字符串中分离出文件名
*/
private String getFileName(String line) {
Matcher m = Pattern.compile("filename=\"([^\"]*)\"").matcher(line);
if(m.find()){
String name = m.group(1);
int offset = name.lastIndexOf("\\");
name = name.substring(++offset);
offset = name.lastIndexOf("/");
name = name.substring(++offset);
return name;
}
return "";
}
/***
* 从描述字符串中分离出字段名
*/
private String getKey(String line) {
Matcher m = Pattern.compile("name\\=\"([^\"]*)\"").matcher(line);
if(m.find()) return m.group(1);
return "";
}
/***
* 不用正则表达式分割字符串
*/
private static String[] split(String line, String mark) {
if (line == null) return null;
StringTokenizer st = new StringTokenizer(line, mark);
ArrayList<String> tmp = new ArrayList();
while (st.hasMoreTokens()) tmp.add(st.nextToken());
String[] strArr = tmp.toArray(new String[tmp.size()]);
tmp.clear();
return strArr;
}
private static byte[] arraycopy(byte[] source, int offset, int len) {
byte[] target = new byte[source.length];
for (int i = offset; i < offset + len; i++) {
target[i] = source[i];
}
return target;
}
}
分享到:
相关推荐
我的实例代码 博文链接:https://zmx.iteye.com/blog/737374
java 文件上传 SWFUPLOAD 多文件上传 异步上传。SWFUPLOAD 是基于flash插件的文件上传,有良好的显示效果。
文件上传一直是B/S结构中很重要的一项功能,在java中并没有很好的实现文件上传的类包,因此出现了一些开源的组件,Smartupload ,commons-fileupload,还有国内的一个"牛人"的(不好意思叫不上名字来),这几个组件中...
AlanXUpload是一个通过flash技术提供批量上传文件的web批量上传组件,用户可以自定义上传的文件类型、大小、数量,上传的地址,上传的处理方式,自定义上传UI,接受服务器发送的反馈信息,并显示所有文件及单个文件...
许多朋友反应使用后,出现Bad Version...1.上传默认方法upload(),指定编码使用upload("编码名称"); 2.下载默认方法downloadFile("要下载的文件路径"),指定编码使用downloadFile("要下载的文件路径", "编码名称")。
SmartUpload 上传组件(中文终极解决版,包括中文文件名上传后乱码,中文参数,下载) 经过呕心沥血的一天一夜,终于搞定SmartUpload组件的所有中文问题,为大家去除有史以来最头痛的中文问题,包括中文参数,中文文件名...
我个人开发的J2EE下的多文件上传组件,简单易用,包括示例工程和源代码。
上传组件 ajax upload java
SmartUpload 上传组件(中文终极解决版,包括中文文件名上传后乱码,中文参数,下载) 经过呕心沥血的一天一夜,终于搞定SmartUpload组件的所有中文问题,为大家去除有史以来最头痛的中文问题,包括中文参数,中文文件名...
myeclipse 下的一个上传的程序,可以直接导入到myeclipse中,直接运行即可,相对路径已经考虑好,直接把webroot下upload文件夹复制到你的其他项目下直接就能用
主要为大家详细介绍了Java组件FileUpload上传文件实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
用java swing写的批量上传组件。分享给大家一起学习,有不足的地方,大家一起完善。呵呵
该代码完整的实现了shiyonglayui技术实现多文件的上传预览和删除功能,下载下来直接导入到开发工具中就可以使用
"宏软JSP上传系统 v2.0完美版_upload-v2.rar" 是一个针对Java服务器页面(JSP)技术开发的文件上传系统软件包。这个资料包含有经过精心编写和优化的JSP源码,旨在为用户提供一个稳定而高效的文件上传解决方案。该...
利用Struts组件将文件上传到服务器。
fileupload-带进度条java文件上传与下载,包含源代码和说明文档,以及相应的lib包,使用的commons-fileupload-1.2.1组件
javaword的.jar smartupload-CSDN的.jar smartUpload-据说是修正中文错误.jar ======================================================= 在JSP 中上传文件 A.下载上传的工具(SmartUpload) ...
SmartUpload 上传组件(中文终极解决版,包括中文文件名上传后乱码,中文参数,下载) 经过呕心沥血的一天一夜,终于搞定SmartUpload组件的所有中文问题,为大家去除有史以来最头痛的中文问题,包括中文参数,中文文件名...
jsp SmartUpload 组件,经过测试,保证解决上传中文文件名乱码的问题。里面有六个.java文件(ServletUpload.java;SmartFile.java;SmartFiles.java;SmartRequest.java;SmartUpload.java;SmartUploadException.java) ...
jsp实现的基于mootools1.2的flash上传组件,支持多文件无刷新上传。系统通过myeclipse架设。