upload

1 package com.khan.web;
2
3 import java.io.DataInputStream;
4 import java.io.File;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import javax.servlet.http.HttpServletRequest;
9 import java.io.*;
10 import java.util.HashMap;
11
12
13 public class uploadFile {
14 public static final int MAX_SIZE = 1024 * 1024*100;
15 public static final String FILE_DIR = "d:/temp/";
16
17 private int file_Size=0;
18 private String file_Path = "";
19 private HashMap hm = new HashMap();
20
21 public String upLoad(HttpServletRequest req) {
22 String tmpString ="";
23 String result = "";
24 DataInputStream dis = null;
25 String split_Str = "";
26
27 try {
28 dis = new DataInputStream(req.getInputStream());
29 String content = req.getContentType();
30 if (content != null && content.indexOf("multipart/form-data") != -1) {
31
32 int reqSize = req.getContentLength();
33 byte[] data = new byte[reqSize];
34 int bytesRead = 0;
35 int totalBytesRead = 0;
36 int sizeCheck = 0;
37 while (totalBytesRead < reqSize) {
38 // check for maximum file size violation
39 sizeCheck = totalBytesRead + dis.available();
40 if (sizeCheck > MAX_SIZE)
41 result = "文件太大不能上传";
42
43 bytesRead = dis.read(data, totalBytesRead, reqSize);
44 totalBytesRead += bytesRead;
45 }
46 String dataString = null;
47 //dataString = new String(data, "ISO-8859-1");
48 dataString = new String(data);
49 tmpString = new String(data);
50 hm = parseAnotherParam(tmpString);
51
52 //取出字段分割符
53 split_Str = dataString.substring(0, dataString.indexOf("\r\n"));
54 // 分离filepath 并赋值
55 dataString = dataString.substring(dataString.indexOf("filename=\""));
56 String filePath = dataString.substring(0, dataString.indexOf("Content-Type:"));
57 if (filePath==null && filePath.equals("")) return "";
58 //System.out.println(filePath);
59 dataString = new String(dataString.getBytes(),"ISO-8859-1");
60 // 分离contentType 并赋值
61 dataString = dataString.substring(dataString.indexOf("Content-Type:") + 1);
62 dataString = dataString.substring(dataString.indexOf("\n") + 1);
63 // 分离文件信息 获得最终想要的字节
64 //System.out.print("|"+dataString+"|");
65 dataString = dataString.substring(2, dataString.indexOf(split_Str));
66 //System.out.println("|"+dataString+"|");
67 dataString = dataString.substring(0, dataString.lastIndexOf("\n") - 1);
68 //System.out.print("|"+dataString+"|");
69 if (writeFile(dataString.getBytes("ISO-8859-1"), FILE_DIR + getFileName(filePath))) {
70 this.file_Size = dataString.getBytes("ISO-8859-1").length;
71 this.file_Path = FILE_DIR + getFileName(filePath);
72 result = "文件上传完毕";
73 } else {
74 result = "文件上传失败";
75 }
76 } else {
77 result = "content 必须为 multipart/form-data";
78 }
79 } catch (UnsupportedEncodingException ex4) {
80 result = "getBytes 失败 UnsupportedEncodingException错误";
81 } catch (NullPointerException e) {
82 result = "getBytes 失败 NullPointerException错误";
83 } catch (IOException ex1) {
84 result = "IOException 错误 ";
85 }
86
87 return result;
88 }
89
90 public String getFilePath(){
91 return this.file_Path;
92 }
93
94 public int getFileSize(){
95 return this.file_Size;
96 }
97
98 public boolean writeFile(byte[] data, String path) {
99 File f = null;
100 FileOutputStream fos = null;
101 try {
102 f = new File(path);
103 f.createNewFile();
104 fos = new FileOutputStream(f);
105 fos.write(data, 0, data.length);
106 } catch (FileNotFoundException e) {
107 return false;
108 } catch (IOException e) {
109 return false;
110 } finally {
111 try {
112 fos.close();
113 } catch (IOException e) {
114 return false;
115 }
116 }
117 return true;
118 }
119
120 public String getFileName(String arg) {
121 String path = "";
122 if (arg.indexOf("\"") > -1)
123 path = arg.substring(arg.indexOf("\"") + 1, arg.lastIndexOf("\""));
124 else
125 path = arg;
126 //System.out.println("file_path:"+arg);
127 path = path.substring(path.lastIndexOf("\\") + 1);
128 return path;
129 }
130
131
132 public HashMap parseAnotherParam(String str){
133 HashMap hm= new HashMap();
134 String key="";
135 String value="";
136 int startindex = 0;
137 int endindex = 0;
138
139 startindex = str.indexOf("Content-Dis;form-data; name=\"") + "Content-Dis;form-data; name=\"".length();
140 endindex = str.indexOf("\"\r\n\r\n");
141
142 while ( startindex >-1 && endindex > -1 ){
143 key = str.substring(startindex, endindex);
144
145 if(!str.substring(endindex , endindex + 5).equals("\"\r\n\r\n") ){//去掉没有value的元素
146 str = str.substring(endindex);
147 startindex = str.indexOf("Content-Dis;form-data; name=\"") + "Content-Dis;form-data; name=\"".length();
148 endindex = str.indexOf("\"\r\n\r\n");
149 continue;
150 }
151 if( key.indexOf("\";") > -1){//去掉上传文件的参数以及编码
152 str = str.substring(str.indexOf("\";") + 2);
153 startindex = str.indexOf("Content-Dis;form-data; name=\"") + "Content-Dis;form-data; name=\"".length();
154 endindex = str.indexOf("\"\r\n\r\n");
155
156 continue;
157 } else
158 str = str.substring(endindex + 5);
159
160 value = str.substring(0, str.indexOf("\r\n"));
161 str = str.substring(str.indexOf("\r\n") + 2);
162 //System.out.println("key:"+key+" value:"+value);
163 hm.put(key,value);
164
165 startindex = str.indexOf("Content-Dis;form-data; name=\"") + "Content-Dis;form-data; name=\"".length();
166 endindex = str.indexOf("\"\r\n\r\n");
167
168 }
169 return hm;
170 }
171
172 public String getParameter(String param){
173 //System.out.println(hm.toString());
174 return (String)hm.get(param);
175 }
176
177
178 }


调用方式如下:

com.khan.web.uploadFile upload = new com.khan.web.uploadFile();

//上传文件
out.print("<p><a>文件上传状态:" + upload.upLoad(request) + "</a></p>");
//取得上传文件的大小
strs[0][5] = String.valueOf(upload.getFileSize()) ;


//取得跟随文件一起提交的表单中其他参数
String filepath = upload.getParameter("filepath");
String file_type = upload.getParameter("file_type");
String songstyle = upload.getParameter("songstyle");

计划下一步增加同时上传多个文件的功能


1. org.apache.struts.upload.*;

这个比较操作上比较简单,用FormFile 得到一个上传文件的FormFile对象,对象中保存了上传文件的名字信息,上传表单子段信息和本地上传地址以及上传文件的流信息。然后再写到服务器文件中就ok了






// …
// ① 检查输入请求是否为multipart的表单数据。 FormFile image = myform.getImagefile(); // imagefile为FormFile对象; String basepath = Utils.getBasePath(request); if (null != image && image.getFileSize() > 0) { imagename = member_id + "." + Utils.getFormFileType(image); //得到保存文件的类型 } Utils.saveFile(basepath, "memimage", imagename, image);




// …
public static String getFormFileType(FormFile file) { String type = ""; int tmp = file.getFileName().indexOf("."); if (tmp > 0) { type = file.getFileName().substring(tmp + 1); } return type; } public static void saveFile (StringbasePath,String subPath,String fileName,FormFile file) throws Exception { if (null == file || file.getFileSize() < 1) { return; } String filePath = basePath + "upload\\" + subPath+"\\"; File fileTmp = new File(filePath); if (fileTmp.exists()) { if (!fileTmp.isDirectory()) { throw new AppException("文件保存路径错误!"); } } else { fileTmp.mkdirs(); } fileTmp = new File(filePath + fileName); FileOutputStream fo = new FileOutputStream(fileTmp); fo.write(file.getFileData()); fo.close(); }



2.Jakarta Commons.FileUpload

首先创建一个HTML页面。注意,凡是要上载文件的表单都必须设置enctype属性,且属性的值必须是multipart/form-data,同时请求方法必须是POST。下面的表单除了上载两个文件,另外还有一个普通的文本输入框:


<form name="myform" action="fileuploaddemo.jsp"
method="post" enctype="multipart/form-data">
输入你的名字:<br />
<input type="text" name="name" size="15"/><br />
图形:<br />
<input type="file" name="imagefile"><br/>
文件:<br />
<input type="file" name="myfile"><br /><br />
<input type="submit" name="Submit"
value="Submit your files"/>




// …
// ① 检查输入请求是否为multipart的表单数据。
boolean isMultipart = FileUpload.
isMultipartContent(request);
// …
// ② 为该请求创建一个句柄,通过它来解析请求。执行
// 解析后,所有的表单项目都保存在一个List中。
DiskFileUpload upload = new DiskFileUpload();
// 通过句柄解析请求,解析得到的项目保存在一个List中
List items = upload.parseRequest(request);
// …
// ③ 通过循环依次获得List里面的文件项目。要区分表示
// 文件的项目和普通的表单输入项目,使用isFormField()
// 方法。根据处理请求的要求,我们可以保存上载的文
// 件,或者一个字节一个字节地处理文件内容,或者打
// 开文件的输入流。
Iterator itr = items.iterator();

while(itr.hasNext()) {
FileItem item = (FileItem) itr.next();

// 检查当前的项目是普通的表单元素,还是一个上载的文件
if(item.isFormField()) {
// 获得表单域的名字
String fieldName = item.getFieldName();
// 如果表单域的名字是name…
if(fieldName.equals("name"))
request.setAttribute("msg",
"Thank You: " + item.getString());

} else {
// 该项目是一个上载的文件,把它保存到磁盘。
// 注意item.getName()
// 会返回上载文件在客户端的完整路径名称,这似乎是一个BUG。
// 为解决这个问题,这里使用了fullFile.getName()。
File fullFile = new File(item.getName());
File savedFile = new File
(getServletContext().getRealPath("/"),
fullFile.getName());
item.write(savedFile);
}
}



  我们可以通过上载句柄的upload.setSizeMax来限制上载文件的大小。当上载文件的大小超过允许的值时,程序将遇到异常。在上面的例子中,文件大小的限制值是-1,表示允许上载任意大小的文件。

  还有其他一些略有变化的使用形式,正如前面所指出的,我们可以在上载的文件上打开一个输入流,或者让它们驻留在内存中直至空间占用达到一定的限制值,或者在判断文件类型的基础上,以String或Byte数组的形式获取其内容,或者直接删除文件。这一切都只要使用FileItem类提供的方法就可以方便地做到(DefaultFileItem是FileItem的一个实现)。


JAVA上传文件比较与实例
jsp文件上传大多采用采用开源项目来简化处理,这里列出常用的两个jar包的实现,并进行比较,说明他们的优缺点和应该注意的问题。
Commons FileUpload,可以在http://jakarta.apache.org/commons/fileupload/下载,这个包需要Commons IO的支持,可以在http://jakarta.apache.org/commons/io/下载
com.oreilly.servlet,可以在http://www.servlets.com/cos/下载
Commons FileUpload提供三种文件上传处理方式,DiskFileUpload、ServletFileUpload和PortletFileUpload三种方式,其中DiskFileUpload已经在javadoc下已经被标记为过期的方法,建议用ServletFileUpload代替,而PortletFileUpload需要配合portlet-api来使用,所以这里我们只介绍ServletFileUpload,并且这个也是最常用的。
com.oreilly.servlet也提供了三种文件上传的处理方式,MultipartWrapper、MultipartRequest和MultipartParser三种方式,其中MultipartWrapper和MultipartRequest的用法基本相同,并且没有MultipartRequest提供的操作多,所以这里介绍MultipartRequest,MultipartParser和前两者有些不同,可以用来处理某些特殊情况,例如表单中有两个同名的文件上传选择框。
我们暂时称三面三种文件上传方式分别为:ServletFileUpload方式(MultipartTestServlet)、MultipartRequest方式(MultipartTestServlet2)、MultipartParser方式(MultipartTestServlet3)
代码如下:
test.html
<%@ page language="java" import="java.util.*" contentType="text/html;charset=gbk" pageEncoding="gbk"%>
<html>
<body>
<form action="MultipartTestServlet" enctype="multipart/form-data" method="post">
<input type="text" name="username" /><br />
<input type="file" name="myfile" /><br/>
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
<br/><br/><br/><br/>
<form action="MultipartTestServlet2" enctype="multipart/form-data" method="post">
<input type="text" name="username" /><br />
<input type="file" name="myfile" /><br/>
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
<br/><br/><br/><br/>
<form action="MultipartTestServlet3" enctype="multipart/form-data" method="post">
<input type="text" name="username" /><br />
<input type="file" name="myfile" /><br/>
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
</body>
</html>
MultipartTestServlet.java
package com.bug.servlet;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
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.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
public class MultipartTestServlet extends HttpServlet {
public MultipartTestServlet() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("gbk");
RequestContext requestContext = new ServletRequestContext(request);

if(FileUpload.isMultipartContent(requestContext)){

DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("c:/tmp/"));
ServletFileUpload upload = new ServletFileUpload(factory);
//upload.setHeaderEncoding("gbk");
upload.setSizeMax(2000000);
List items = new ArrayList();
try {
items = upload.parseRequest(request);
} catch (FileUploadException e1) {
System.out.println("文件上传发生错误" + e1.getMessage());
}
Iterator it = items.iterator();
while(it.hasNext()){
FileItem fileItem = (FileItem) it.next();
if(fileItem.isFormField()){
System.out.println(fileItem.getFieldName() + " " + fileItem.getName() + " " + new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));
}else{
System.out.println(fileItem.getFieldName() + " " +
fileItem.getName() + " " +
fileItem.isInMemory() + " " +
fileItem.getContentType() + " " +
fileItem.getSize());

if(fileItem.getName()!=null && fileItem.getSize()!=0){
File fullFile = new File(fileItem.getName());
File newFile = new File("c:/temp/" + fullFile.getName());
try {
fileItem.write(newFile);
} catch (Exception e) {
e.printStackTrace();
}
}else{
System.out.println("文件没有选择 或 文件内容为空");
}
}

}
}
}
}
MultipartTestServlet2.java
package com.bug.servlet;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
public class MultipartTestServlet2 extends HttpServlet {
public MultipartTestServlet2() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//request.setCharacterEncoding("gbk"); 不起作用
System.out.println("start ");
MultipartRequest multi = new MultipartRequest(request, "c:/tmp/", 2*1024*1024, "gbk", new DefaultFileRenamePolicy());
System.out.println("start ");
Enumeration filesName = multi.getFileNames();
Enumeration paramsName = multi.getParameterNames();
while(paramsName.hasMoreElements()){
String paramName = (String) paramsName.nextElement();
System.out.println(multi.getParameter(paramName));
}
while(filesName.hasMoreElements()){
String fileName = (String) filesName.nextElement();
System.out.println(multi.getFilesystemName(fileName) + " " +
multi.getOriginalFileName(fileName) + " " +
multi.getContentType(fileName) + " ");
if(multi.getFilesystemName(fileName)!=null && !multi.getFilesystemName(fileName).equals(""))
System.out.println(multi.getFile(fileName).toURI());
}
}

}
MultipartTestServlet3.java
package com.bug.servlet;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;
public class MultipartTestServlet3 extends HttpServlet {
public MultipartTestServlet3() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
MultipartParser mp = new MultipartParser(request, 2*1024*1024, false, false, "gbk");
Part part;
while ((part = mp.readNextPart()) != null) {
String name = part.getName();
if (part.isParam()) {
ParamPart paramPart = (ParamPart) part;
String value = paramPart.getStringValue();
System.out.println("param: name=" + name + "; value=" + value);
}
else if (part.isFile()) {
// it's a file part
FilePart filePart = (FilePart) part;
String fileName = filePart.getFileName();
if (fileName != null) {
long size = filePart.writeTo(new File("c:/tmp/"));
System.out.println("file: name=" + name + "; fileName=" + fileName +
", filePath=" + filePart.getFilePath() +
", contentType=" + filePart.getContentType() +
", size=" + size);
}
else {
System.out.println("file: name=" + name + "; EMPTY");
}
System.out.flush();
}
}
}
}
web.xml中加入
<servlet>
<servlet-name>MultipartTestServlet</servlet-name>
<servlet-class>com.bug.servlet.MultipartTestServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>MultipartTestServlet2</servlet-name>
<servlet-class>com.bug.servlet.MultipartTestServlet2</servlet-class>
</servlet>
<servlet>
<servlet-name>MultipartTestServlet3</servlet-name>
<servlet-class>com.bug.servlet.MultipartTestServlet3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MultipartTestServlet</servlet-name>
<url-pattern>/MultipartTestServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MultipartTestServlet2</servlet-name>
<url-pattern>/MultipartTestServlet2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MultipartTestServlet3</servlet-name>
<url-pattern>/MultipartTestServlet3</url-pattern>
</servlet-mapping>
问题1、中文问题:
三种凡是都可以通过自己的方法来设置encoding为gbk开处理和解决中文问题,包括初始化的时候传入gbk作为参数,或是是初始化后通过setEncoding的方式来实现。
另外ServletFileUpload方式也可以通过request.setCharacterEncoding("gbk");的方式来实现,而其它两种方式不支持这种方式。

问题2、文件大小限制
ServletFileUpload方式可以设置文件大小限制,也可以不用设置,例子中的upload.setSizeMax(2000000)就可以注释掉。如果设置upload.setSizeMax(-1),表明不限制上传的大小。文档中没有指明默认的限制的多少,我在不设置的情况下上传了一个9M的东西,可以上传,估计默认是不限制大小的。
而MultipartRequest方式和MultipartParser方式是必须设置文件的上传文件的大小限制的,如果不设置,默认是1M的大小限制。

问题3、文件上传发生错误
如果文件上传过程中发生任何错误,或者是文件的大小超出了范围,系统都将抛出错误。
ServletFileUpload方式在upload.parseRequest(request)时抛出错误
MultipartRequest方式在new MultipartRequest(。。。)时抛出错误
MultipartParser方式在new MultipartParser(。。。)时抛出错误

问题4、上传同名文件时,他们保存到临时目录是的冲突问题
ServletFileUpload方式,不会有冲突,系统会把上传得文件按照一定的规则重新命名,保证不会冲突
MultipartParser方式,会产生冲突,系统会把文件按照上传时的文件名,保存到临时目录下,如果两个用会同时上传文件名相同的文件,那么就可能会产生冲突,一方把另一方的临时文件给替换了。
MultipartRequest方式,在初始化时如果提供了一个名称转换策略,就不会有冲突,如果不提桶,就会有冲突。在上面的例子中我们提供了一个new DefaultFileRenamePolicy()保证了文件名不会有冲突发生。

问题5:表单中有两个同名的文件上传选择框,就像我们例子中的myfile一样,每个表单中有两个name=“myfile”的上传框
ServletFileUpload方式,可以处理,可以分别得到他们各自的文件,
MultipartRequest方式,不可以处理,会发生冲突,会有一个上传框的文件覆盖了另外一个。
MultipartParser方式,可以处理,可以分别得到他们各自的文件,

备注:
代码比较乱,主要是为了说明他们间的区别。他们的详细地使用说明还是要参考他的javadoc和domo。
参考:
1、http://www.servlets.com/cos/#classes
2、http://jakarta.apache.org/commons/fileupload/apidocs/index.html
3、http://jakarta.apache.org/commons/fileupload/using.html
4、http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值