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

 

一、struts2文件上传用的是commons-fileupload的上传组件。
二、上传文件时表单的提交方式一定要是postenctype属性一定要是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包。上传都是以字节的方式上传的。一般用的是用apachecommons-fileupload-1.2.1.jar上传。
六、upload2.jspresult2.jspcom.test.servlet.UploadSevlet是实现一个文件上传的基本要用时把web.xml里的struts2配置注释掉。
七、org.apache.commons.fileupload.disk.DiskFileItemFactory它是一传文件的出发点,它的setRepository方法是用于设置一个文件保存的临时目录,它有两种情况一种是上传文件小的时候就直接放到内存中,而大时就在磁盘上建一个临时目录存放,而这个方法就是设置临时目录的。而setSizeThreshold是设置超出文件大小时放入磁盘的路径,它是设置这个限制的。
八、DiskFileItemFactory是用来创建上传的实例的。org.apache.commons.fileupload.DiskFileUploadorg.apache.commons.fileupload.servlet.ServletFileUpload是用来处理文件上传的,一般用后者代替前者。
九、创建ServletFileUpload可以用DiskFileItemFactory类的实例去构建。它里面的parseRequest方法是处理上传的,它返回集合,里面是客户端里所有的字段信息,这个集合可以是List<FileItem>型。
十、去遍历这个集合,用FileItem类的isFormField用于判断是否是文件上传字段,是返回false否则返回true
十一、FileItemgetFieldName返回客户端的字段名字、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里把数组与集合是同样的。
十八、strut2org.apache.struts2.org.apache.struts2是全局属性的设置,可以用constant去修改,而struts-default.xml主要是拦截器与结果类型的设置。struts2支持三种类型的文件上传:cospelljakartajakarta是默认的。
十九、org.apache.struts2.interceptor.FileUploadInterceptor类是一个上传文件拦截器类,它里面有两个很重要的属性:allowedTypesSetmaximumSize。它们是允许上传的类型与最大大小,要使用它们就要把fileUploaddefaultStack拦截器栈里提取出来单独在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是在confweb.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-typenamestream的方式的返回类型,它是用org.apache.struts2.dispatcher.StreamResult这个类来实现的。
二十七、也就是说还需要写一个文件下载的action
二十八、在org.apache.struts2.dispatcher.StreamResult这个返回结果里主要有下载类型contentType下载文件名字contentDisposition、下载的IO流入口inputName(是用于配置返回InputStream类的方法的,它采用的是javabeanget属性规范,只写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。

  1. <%
  2.     //取得服务器"/download/file"目录的物理路径
  3.      String path = request.getRealPath("/upload");
  4.     //取得"/download/file"目录的file对象
  5.      File file = new File(path);
  6.     //取得file目录下所有文件
  7.      File[] files = file.listFiles();
  8.   
  9.    for (int i = 0; i < files.length; i++) {
  10.   
  11.      String fname = files[i].getName();
  12.   
  13.     //对文件名进行url编码(UTF-8指明fname原来的编码,UTF-8一般由本地编码GBK代替)
  14.       fname = java.net.URLEncoder.encode(fname, "UTF-8");
  15.   
  16.     out.println("<a href=download2.action?name=" + fname + "&len=" + files[i].length() + ">"
  17.       + files[i].getName() + "</a><br>");
  18.      }
  19.     %>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值