分享
 
 
 

通用上载组件的原理及实现

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

JSP/SERVLET上载的难点

1、支持任意格式、任意数量的文件上载;2、上载控制的实现;3、表单信息的取得;4、“即插即用”的应用方法;我个人认为,制约通用 上载组件的实现主要是这四个难点。

JSP/SERVLET上传的原理

JSP/SERVLET文件 上载是通过ServletInputStream类来实现的,ServletInputStream类是java.io.InputStream的一个扩展抽象类,实质上也是一个输入流,通过ReadLine方法从Request端一行一行读取,可见,JSP/SERVLET上载根本上是用流来实现的,理解了这个就不难理解整个 上载的原理。ServletInputStream实现文件 上载必须采用HTTP POST或者HTTP PUT协议,HTTP GET协议只能传递很少的数据,是不能实现文件上载的。

下面我们来看一下上传的数据流的结构,首先要在BROWSER端给出一个请求,我们的请求如下(文件名为test1.jsp):

<%@ page contentType="text/html; charset=GBK" %

<html

<head

<title文件上载</title

</head

<body

<form action="test2.jsp" enctype="MULTIPART/FORM-DATA" method=post

说明一: <input type="text" name="explain1" /

<br /

说明二: <input type="text" name="explain2" /

<br /

请选择上载文件1 <input type="file" name="file1" /

<br /

请选择上载文件2 <input type="file" name="file2" /

<br /

说明三: <input type="text" name="explain3" /

<br /

<input type="submit" value=" 上

载 " /

</form

</body

</html

显示如下:

说明一:

说明二:

请选择上载文件一:

请选择上载文件二:

说明三:

在上载请求页中混杂了表单的三个输入框,及两个上载文件,当然输入框可以更多、更杂,可以有选择框、单选及多选按钮,待上传的文件也可以有三个、四个或所需要的更多。

action="test2.jsp"表示表单将提交到"test2.jsp",另外注意表单属性中必须要有这句:enctype="MULTIPART/FORM-DATA",enctype指定 Form 输入资料的编码方式,“method”属性必须为“post”,这样表单才能提交大量数据,也表示本表单的数据传递将用流操作,“method=get”表示数据将通过地址栏进行传递,虽然方便快捷,但只适合很少的数据量。

响应端“test2.jsp”页面如下:

<%@ page contentType="text/html; charset=GBK" %

<html

<head

<title文件上载</title

</head

<body

<jsp:useBean id="upBean" scope="page" class="com.upload.UpBean"/

<%

upBean.doUpload(request);

out.println("上载已完成,请查看输出文件");

%

</body

</html

test2.jsp收到请求后,调用一个java bean执行doUpload(request)操作,本操作将完成流(unicode格式)的接收并不做任何处理地将流顺序写入一个文本文件里,读写操作中用了一个缓冲区byte[] readByte,用了一个ServletInputStream 的一个方法readLine(byte[] b, int off,int len)方法读取流,请大家注意,ServletInputStream 流的read Line方法是一次读入指定大小的行,java bean (UpBean.java)代码如下:

[code]package com.upload;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.ServletInputStream;

public class UpBean {

public void doUpload(HttpServletRequest req) throws ServletException, IOExcept

ion{

//首先定义一个文本文件

File file = new File("out.txt");

//readCount 记录从输入流中实际读取的字符数

int readCount;

//输入流缓冲区

byte[] readByte = new byte[1024];

//初始化输入流

ServletInputStream servletInputStream = req.getInputStream();

//初始化一个输出流(到文件)

FileOutputStream fileOutputStream = new FileOutputStream(file);

//循环从读取输入流中读取字节

readCount = servletInputStream.readLine(readByte, 0,readByte.length);

while(readCount != -1){

fileOutputStream.write(readByte,0,readCount);

readCount = servletInputStream.readLine(readByte, 0, 1024);

}

//关闭文件流

fileOutputStream.flush();

}

}[/code]

为了便于我们阅读流,上载的两个文件为两个简单的文本文件(有格式的文件,不便于直接分析):one.txt及two.txt,文件内容如下,实验时请建立对应文本文件,内容请直接copy以下所示:

one.txt:

one

one one

one one one

two.txt

two

two two

two two two

都准备好以后,我们就可以运行了,运行时请注意,文本部分及文件部分最好不要出现汉字,或其他双字符集字符,尽量采用英文,因为接收是采用的Unicode字符集,我们未对输入做任何处理。 我们在三个输入框输入的字符为,说明一:explain1;说明二:explain2;说明三:explain3,out.txt接收到如下字符:

-----------------------------7d2623a3e0286

Content-Disposition: form-data; name="explain1"

explain1

-----------------------------7d2623a3e0286

Content-Disposition: form-data; name="explain2"

explain2

-----------------------------7d2623a3e0286

Content-Disposition: form-data; name="file1"; filename="C:\test\one.txt"

Content-Type: text/plain

one

one one

one one one

-----------------------------7d2623a3e0286

Content-Disposition: form-data; name="file2"; filename="C:\test\two.txt"

Content-Type: text/plain

two

two two

two two two

-----------------------------7d2623a3e0286

Content-Disposition: form-data; name="explain3"

explain3

-----------------------------7d2623a3e0286--

可以很明显的看到,out.txt被“-----------------------------7d2623a3e0286”分成了五 节,即表单的每个输入部分都对应一节,结尾部分是“-----------------------------7d2623a3e0286--”,刚好比开始的一段字符在最后多出两个“-”, 每节的第一行是输入内容的说明“Content-Disposition: form-data”,“name="explain1"”表示 上载请求项的name,文本输入部分仅这两个说明,如果输入的是文件还用两项说明:“filename="C:\test\one.txt"”,表示输入源,基于ms-windows的ie上载带有完整的路径,netscape及其他浏览器可能只有一个文件名;还有一项是关于输入格式的“Content-Type:text/plain”;表示输入格式是文本类型,如果我们上载的是bmp文件则为“Content-Type: image/bmp”,word文件为“application/msword”...,说明的下面紧接着是一个空行,然后下面才是我们所需的内容。

仔细分析未加修改的输入流格式,有助于我们实现文件与输入文本的准确分离。

通过以上的分析可以看出,准确分离上载的文件及文本信息需要以下要素:1、数据段分割符、结束符(比分割符多出两个“-”);2、输入文本及上载的文件区分标志(文本为“name=”,文件为“filename=”);3、编码格式,可以通过HttpServletRequest 类getCharacterEncoding() 方法取得。4、表单文本部分名称及内容,名称为“name=”后面的字符,内容为该段第三行及以后的内容;5、文件名称及内容,名称为“filename=”后面的字符,内容为该段第三行及以后的内容。

下面我们将讨论输入流的分离。

程序实现分析

我们首先画出程序实现的主体结构图,请注意判断文件标志(indexOf("filename=")0),与判断文本标志(indexOf("name=")0)的顺序,当(indexOf("filename=")0)成立时,(indexOf("name=")0)一定也是成立的,所以判断文件要在判断文本前。

分离文件及输入文本,为完整保存上载的文件信息及输入的文本信息,本程序建立了两个类:public class FileInfo 、public class InputField,及两个线性表private ArrayList upFilesList、private ArrayList inputFieldList,用于动态增加文件信息及文本信息,定义如下:

FileInfo.java(记录上载文件信息)

package com.upload;

public class FileInfo {

private String fileName;

private boolean validFlag;

private String filePath;

private long fileSize;

//设置文件信息

//上载文件是否有效标志

public void setValidFlag(boolean validFlag){

this.validFlag = validFlag;

}

//文件名

public void setFileName(String filename){

this.fileName = filename;

}

//存贮路径

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有