日期:2014-05-16  浏览次数:20364 次

一个简单的jsp无框架文件上传(菜鸟专用)
我自己就是一个新手,希望大家能多多指正。
无框架,就是不需要其他组件,如Struts2中文件上传之类的。

流程:
一:提交表单时将form中的enctype属性设为multipart/form-data;

二:用getInputStream方法获得上传的数据流,然后用FileOutputStream保存为一个临时文件,用File对象打开该文件;
三:建立一个随机访问文件(RandomAccessFile)读取刚才创建的File对象;
四:用readLine()方式,读取到上传文件的开头;因为上传的数据流里包含了表单的其他信息,以及一些特有的域划分标记(这些内容我并不清楚怎么出来的,可能是内部机制吧)每个请求都有那些数据,因此我只要区分出来,就能取到正确的文件开头,有些文件不用取到正确的文件开头也能打开,但是MD5码却和原来的文件不一样;所以取到正确的文件开头很有必要。还有一点就是取到文件的结尾,如果把<input type="file">放在表单末尾的话,那么文件的结尾就是临时文件的长度-48;这个数字是我反复测试的出来,保存的文件的MD5和原来的一致,说明它们是一样的。下面举例子说明上传的临时文件的结构(有兴趣的可以自己去看看,将数据流保存为一个临时文件,然后用写字板等文本方式打开就能看到)
-------------------4dsf43fffd
xxxxxxxxxxxxx name="xxxx"

asdasd
-------------------4dsf43fffd
XXXXXX name = "bbbb"

ddddff
-------------------4dsf43fffd
xxxxxxxxxxxx name="ccccc" filename="D:\"
xxxx type= xxxxx

asdasdadaasdsad(正确的文件)dsfsdf
sdfsdf
ssdf
sdf
sdf
sdf
sdfsdfsdgdsvx
-------------------4dsf43fffd
大致的结构就是上面的样子;name=是定义的表单的对象,如<input type="text" name="abc"/>
name="abc"就会出现在上面,并且会隔两行到下一个域;当到达文件域时,隔两行刚好是文件的开头;而结尾-48刚好是文件的结尾;因此,我只要用随机访问文件(可以随意定义到文件的任何位置开始读取,可以参看CORE JAVA 第二卷)读取文件开头和结尾之间的内容,就能得到我上传的文件了。
五:用正则判断是否到了文件域,如果到了,读取的该行数据保留下来并解释出文件名,然后读两行;保存文件指针,long start=random.getFilePosition();
六:新建一个File对象f2,用于保存文件,新建一个RandomAccessFile用于把数据保存进f2;从start读到文件结尾,并保存,文件就能正确上传了。
下面是代码
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Index</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form enctype="multipart/form-data" action="upload.jsp" method="POST">
<select name="toDir">
<option value="all">all</option>
<option value="default" selected="selected">default</option>
</select>
<input type="text" name="Myname" value="Hello" />
文件<input type="file" name="upload" />
<input type="submit" value="提交" />
</form>
</body>
</html>

upload.jsp
<%@ page language="java" import="java.util.*,java.io.*"
pageEncoding="UTF-8"%>
<%@page import="java.util.regex.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Upload</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
InputStream input = request.getInputStream();//取得上传的数据流
File fi = new File("D:\\uptem");//新建用于保存上传数据流的临时文件
FileOutputStream o = new FileOutputStream(fi);//将数据流保存为文件
int n;                                        //
byte[] b = new byte[1000000];                 //设置字节缓冲区
while ((n = input.read(b)) != -1) {           //逐个读取
    o.write(b, 0, n);                         //逐个写入
}