zoukankan      html  css  js  c++  java
  • Struts2文件上传与下载

    Struts2框架通过对Common-FileUpload框架进行封装实现文件上传,主要包含两个jar包:commons-io.jar和commons-fileupload.jar

    第一步:完成文件上传的要求

    1. 表单提交方式使用post(因为get方式会有地址长度限制)
    2. form标签的enctype属性值,修改为multipart/form-data(该编码格式会以二进制流方式处理表单)
    3. 在表单中增加文件上传项,<input type="file" name="upload"/>

    第二步:在Action中得到上传文件和文件名

    在action中定义成员变量,并生成set/get方法。注意:File变量的名是表单中文件上传项的name值,文件名也有特定格式

        //文件上传
        private File upload;
        //文件上传名(固定格式)文件变量名+FileName
        private String uploadFileName;
    
        public File getUpload() {
            return upload;
        }
    
    
        public void setUpload(File upload) {
            this.upload = upload;
        }
    
    
        public String getUploadFileName() {
            return uploadFileName;
        }
    
    
        public void setUploadFileName(String uploadFileName) {
            this.uploadFileName = uploadFileName;
        }

    第三步:在Action中实际添加的方法中编写代码

    这里是上传到D:abc这个路径,并且使用了FileUtils类,不要导错包

    import org.apache.commons.io.FileUtils;
            if(upload!=null){
                File newFile=new File("D:\abc"+File.separatorChar+uploadFileName);
                FileUtils.copyFile(upload, newFile);
            }

    当然,也可以使用Java的IO操作

    要导入的包:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;

    操作代码:

            if(upload!=null){
                InputStream is=new FileInputStream(getUpload()); //根据上传的文件得到输入流
                OutputStream os=new FileOutputStream("D:\abc"+File.separatorChar+uploadFileName);//指定输出位置
                byte buffer[]=new byte[1024];
                int count=0;
                while((count=is.read(buffer))!=-1){
                    os.write(buffer,0,count);        //把文件写到指定位置的文件中
                }
                os.close();
                is.close();
            }

    存在的问题:

    struts2文件上传的默认大小是2MB,超过该大小会报异常,浏览器会显示404的错误

    解决办法是:在struts.xml文件中修改属性,进行自定义文件上传大小

    加上下面这句话就可以了,value值是以字节为单位的

    <!-- 设置文件上传大小 -->
    <constant name="struts.multipart.maxSize" value="209715200"></constant>

    但是有可能上传超过我们设置大小的时候,还是会抛异常。可以在struts.xml文件的action配置中增加一个input返回结果,转跳到一个页面,用于提示或者显示失败

    <result name="input">/jsp/error.jsp</result>

    多文件上传

    页面:

    值得注意的是几个<s:file>标签的名字必须相同,这样取值的时候会把它们对应的值都封装到List中

    <s:form action="" method="post" enctype="multipart/form-data">
      <s:file name="upload" label="上传文件一"/>
      <s:file name="upload" label="上传文件二"/>
      <s:file name="upload" label="上传文件三"/>
      <s:submit value="上传"/>
    </s:form>

    效果:

    Action中的编码:

    还是生成set/get方法,只不过要用List封装

    private List<File> upload;
    
    private List<String> uploadFileName;
    
    public List<File> getUpload() {
        return upload;
    }
    public void setUpload(List<File> upload) {
        this.upload = upload;
    }
    public List<String> getUploadFileName() {
        return uploadFileName;
    }
    public void setUploadFileName(List<String> uploadFileName) {
        this.uploadFileName = uploadFileName;
    }

    在具体的操作方法中添加

        if(upload!=null){
            for(int i=0;i<upload.size();i++){
                File newFile=new File("D:\abc"+File.separatorChar+uploadFileName.get(i));
                FileUtils.copyFile(upload.get(i), newFile);
            }
        }

    上传图片文件到数据库

    现将MySQL数据库的相应字段设置为Blob类型(用于存储二进制数据),MySQL中,BLOB是个类型系列,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是在存储文件的最大大小上不同

    MySQL的四种BLOB类型

    类型 大小(单位:字节)
    TinyBlob 最大 255
    Blob 最大 65K
    MediumBlob 最大 16M
    LongBlob 最大 4G

    作为一张图片来说,65k左右应该够用,不过现在很多图片的分辨率较高,也有几兆大小的,那时就换用MediumBlob

    数据库字段完成之后,就开始编写代码:

    这里我使用Java的I/O操作,将图片转换为二进制

                File file = getPicture2();        //Struts2文件上传
                byte[] buffer = null;
                if (file != null) {                  //判断文件是否为空
                    FileInputStream fis = new FileInputStream(file);
                    buffer = new byte[fis.available()];
                    fis.read(buffer);           //二进制流写入buffer
                    fis.close();
                }
            book.setPicture2(buffer);                   //再将buffer给Bean

    最后只要在Dao层完成相应的数据库操作就好了

    文件下载

    对于西欧字符命名的文件,其下载直接在代码中用超链接指向要下载的文件即可:

    <a href="image/example.jpg">下载</a>

    而如果下载的文件中有非西欧字符(如中文)命名的,就不可以这样了,用上面的方法就会报错。Struts2提供的解决办法是:在页面实现一个超链接,它指向一个action请求,然后在对应的Action类中进行一些属性的处理后返回"SUCCESS",最后在action配置文件中的result中用param配置参数完成文件的下载。这些属性如下:

    • inputName:用于指定Action类中作为输入流的属性名
    • contentType:用于指定文件的类型(如果指定该参数,但下载一个图片类型时,会直接在浏览器中打开,若不配置,则会直接下载到硬盘)
    • contentDisposition:该参数用于指定下载文件在客户端上的一些属性(如下载时默认的文件名,注意该文件名最后为西欧字符,如果为中文会出现乱码,用户在下载时可以自行更改)
    • bufferSize:用于指定下载文件时的缓冲区

    例如在WebRoot下建立一个image文件夹,其中放置一个文件“图片.png”

    页面:

    <html>
      <head>
        <title>文件下载</title>
     </head>
     <body>
       <a href="download.action">下载</a>
    </body>
    </html>

    编写Action类(值得注意的是getTargetFile()这个方法与配置文件中的inputName属性值相对应):

    package org.action;
    
    import java.io.InputStream;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class DownloadAction extends ActionSupport {
       private String downloadFile;
    
    //生成downloadFile的set/get方法
    public String getDownloadFile() {
        return downloadFile;   //需要下载的文件路径
    }
    
    public void setDownloadFile(String downloadFile) {         //其值有action配置文件传入
        this.downloadFile = downloadFile;
    }
    
    public InputStream getTargetFile(){        //根据文件名生成它的输入流
        return ServletActionContext.getServletContext().getResourceAsStream(downloadFile);
    }
    
    public String execute() throws Exception {
        return SUCCESS;
    }
       
    }

    配置struts.xml文件:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
        <package name="default" extends="struts-default">
             <action name="download" class="org.action.DownloadAction">
          <!-- 指定下载文件的路径 -->
             <param name="downloadFile">/image图片载.png</param>
          <!--type="stream"指定以流的方式返回-->
                <result name="success" type="stream">
          <!-- 输入流名字,对应Action类中的getTargetfile()方法 -->      
                  <param name="inputName">targetFile</param>
          <!-- 设置下载文件的文件名 -->        
                  <param name="contentDisposition">filename="example.zip"</param>
           <!-- 设置下载文件缓存区大小 -->       
                  <param name="bufferSize">4096</param>
                </result>
             </action>
        </package>
    </struts>
  • 相关阅读:
    python 项目实例
    flash教程
    flask request
    systemd-unit
    kubernets HA集群手动部署
    zookeeper(1)-简单介绍
    apache与nginx原理
    技术文章整理
    CMS垃圾回收器
    Zookeeper
  • 原文地址:https://www.cnblogs.com/lz2017/p/6685798.html
Copyright © 2011-2022 走看看