您的位置:首页 > 编程语言 > Java开发

[转载] 第六章 struts2文件上传与下载

2009-10-30 09:57 351 查看
一、struts2文件上传用的是commons-fileupload的上传组件。
二、上传文件时表单的提交方式一定要是post而enctype属性一定要是multipart/form-data
三、表单的enctype属性默认值是application/x-www-form-urlencoded,它的意思是表单里的所有东西是以字符串的方式提交的,用它提交只可以得到文件的名字。
四、result.jsp是最基本的文件上传结构,用的时候把web.xml里的struts给注释掉。在jsp里空格经过编码后是加号。com.test.url.DecoderTest里是最基本的url解码,URLDecoder是用于URL解码的,URLEncoder是用于编码。
五、加入commons-io-1.3.2.jar包。上传都是以字节的方式上传的。一般用的是用apache的commons-fileupload-1.2.1.jar上传。
六、upload2.jsp、result2.jsp与com.test.servlet.UploadSevlet是实现一个文件上传的基本要用时把web.xml里的struts2配置注释掉。
七、org.apache.commons.fileupload.disk.DiskFileItemFactory它是一传文件的出发点,它的setRepository方法是用于设置一个文件保存的临时目录,它有两种情况一种是上传文件小的时候就直接放到内存中,而大时就在磁盘上建一个临时目录存放,而这个方法就是设置临时目录的。而setSizeThreshold是设置超出文件大小时放入磁盘的路径,它是设置这个限制的。
八、DiskFileItemFactory是用来创建上传的实例的。org.apache.commons.fileupload.DiskFileUpload与org.apache.commons.fileupload.servlet.ServletFileUpload是用来处理文件上传的,一般用后者代替前者。
九、创建ServletFileUpload可以用DiskFileItemFactory类的实例去构建。它里面的parseRequest方法是处理上传的,它返回集合,里面是客户端里所有的字段信息,这个集合可以是List<FileItem>型。
十、去遍历这个集合,用FileItem类的isFormField用于判断是否是文件上传字段,是返回false否则返回true。
十一、FileItem的getFieldName返回客户端的字段名字、getString得到值。如果是文件类型时有的浏览器可能返回这个文件的路径,最后把它处理一下,不然的话可能出现上传路径错误。
十二、然后这样上传文件:OutputStream os = new FileOutputStream(new File(path,filename));
InputStream is = item.getInputStream();
byte[] buffer = new byte[400];
int length = 0;
while((length = is.read()) > 0)
{
os.write(buffer,0,length);
}
os.close();
is.close();
struts2也是用这个实现上传的。
Struts2上传代码:
public String execute() throws Exception {
for (int i = 0; i < file.size(); i++) {
InputStream is = new FileInputStream(file.get(i));
// String root = ServletActionContext.getRequest().getRealPath(
// "/upload");
// String path="D://";
String
path=this.getClass().getResource("/").getPath();//得到d:/tomcat/webapps/工程名WEB-INF/classes/路径
path=path.substring(1,
path.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路劲
path=path+"/upload";
File destFile = new File(path, this.getFileFileName().get(i));//在目的路径下医院文件名创建文件
OutputStream os = new FileOutputStream(destFile);
byte[] buffer = new byte[400];
int length = 0;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);//写入硬盘
}
is.close();
os.close();
}
return SUCCESS;
}
十三、在FileItem里有一个write方法可以代替以上代码。
十四、在struts2里除了指定字段外,客户端的文件类型对应File类型,而文件名是:字段名+FileName,文件类型:字段名+fileContentType这两个属性是必须的,名字也必须是这个类型,主要是在上传的拦截器里要使用。
十五、ServletActionContext.getRequest()得到request对象。
十六、在struts2.xml里加上<constant name="struts.i18n.encoding" value="gbk"></constant>改变默认的编码格式。
十七、在上传多个文件时,把file,FileName,FileContent三个属性改为集合或是数组,strut2里把数组与集合是同样的。
十八、strut2里org.apache.struts2.org.apache.struts2是全局属性的设置,可以用constant去修改,而struts-default.xml主要是拦截器与结果类型的设置。struts2支持三种类型的文件上传:cos、pell、jakarta,jakarta是默认的。
十九、org.apache.struts2.interceptor.FileUploadInterceptor类是一个上传文件拦截器类,它里面有两个很重要的属性:allowedTypesSet与maximumSize。它们是允许上传的类型与最大大小,要使用它们就要把fileUpload从defaultStack拦截器栈里提取出来单独在action里设置参数,注意默认拦截器。代码如下:
<interceptor-ref name="fileUpload">
<param name="maximumSize">4096000</param>
<param name="allowedTypes">application/vnd.ms-powerpoint</param>
</interceptor-ref>
二十、在org.apache.struts2.interceptor.FileUploadInterceptor里允许上传的类型存放在Collections里。要上传的文件类型在应用的服务器里找,Tomcat是在conf的web.xml里,
二十一、在上传文件类型的错误放在field级别里,在页面显示当然要用<s:fielderror>。
二十二、要替换上传文件类型出错信息,要从org.apache.struts2包里的struts-messages.properties文件里找,它里面配置了许多出错的信息。要换替掉文件类型出错信息就只要替换掉里面的struts.messages.error.content.type.not.allowed即可。
二十三、用全局属性文件message.properties替换struts2默认的提示错误信息:
<constant name="struts.custom.i18n.resources" value="message"></constant>,然后在属性文件中加入如下字段
struts.messages.error.content.type.not.allowed=替换的值。
二十四、org.apache.struts2包里的struts-messages.properties文件里的struts.messages.error.file.too.large是文件太大的错误信息struts.messages.error.uploading是统一的错误处理。
二十五、一般下载不可以直接写一个链接链接到这个文件,这样有的浏览器会把它打开,同时也不利于权限的控制,一般用标准http协议的方式,采用二进制流让浏览器认识这流的方式。
二十六、在struts-defaylt.xml里的result-types返回结果里有一个result-type的name是stream的方式的返回类型,它是用org.apache.struts2.dispatcher.StreamResult这个类来实现的。
二十七、也就是说还需要写一个文件下载的action。
二十八、在org.apache.struts2.dispatcher.StreamResult这个返回结果里主要有下载类型contentType、下载文件名字contentDisposition、下载的IO流入口inputName(是用于配置返回InputStream类的方法的,它采用的是javabean的get属性规范,只写get后的名字,第一个字母小写)、缓冲区大小bufferSize(注这些参数要在result里用param来配置而contentDisposition的值应该是filename="XXX"格式 主要是根据http协议)。最关键的属性是inputName,所以在下载的类里一定要有返回InputStream类的方法。
二十九、下载时是先执行返回InputStream的方法后以流的形式返回给用户。

注意:动态下载待研究,还有中文问题经测试支持不好,思路是:
在struts.xml中获取流file的方法是调用action里的InputStream getFile()方法。
那么其它的属性比如说
<param name="contentType">text/plain</param>
这里面的值你写成${type},那么在action里面就要提供获取的方法String getType()。
这时候这里写成<param name="contentType">${type}</param>。
至于如何动态生成这个type的值,你存入数据库的时候肯定存进去了的吧。
其它的文件名啊,contentDisposition都可以用这个方法动态赋给struts.xml。

<%

//取得服务器"/download/file"目录的物理路径

String path = request.getRealPath("/upload");

//取得"/download/file"目录的file对象

File file = new File(path);

//取得file目录下所有文件

File[] files = file.listFiles();

for (int i = 0; i < files.length; i++) {

String fname = files[i].getName();

//对文件名进行url编码(UTF-8指明fname原来的编码,UTF-8一般由本地编码GBK代替)

fname = java.net.URLEncoder.encode(fname, "UTF-8");

out.println("<a href=download2.action?name=" + fname + "&len=" + files[i].length() + ">"

+ files[i].getName() + "</a><br>");

}

%>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: