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>
原文地址:https://www.cnblogs.com/lz2017/p/6685798.html