Struts2实现文件的上传与下载

Posted Java与大数据学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2实现文件的上传与下载相关的知识,希望对你有一定的参考价值。

上传

第一步:静态展示页面

<h1>文件上传</h1>
<form action="/StrutsDay1/test/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="pic" ><br />
    <input type="submit" value="上传">
</form>

注意:

  • method="post",只有post支持二进制的传输方式,

  • 添加enctype属性,并且设置值为“multipart/form-data”,将表单数据以二进制流的形式发送到服务器

  • input type的类型为“file”

第二步:Action接收表单提交的数据,获取到提交的文件,并将获取的文件拷贝到服务器项目所在的目录下

public class FIleUploadAction {
    private File pic;
    private String picFileName;//自动获取文件名

    public String getPicFileName() {
        return picFileName;
    }
    public void setPicFileName(String picFileName) {
        this.picFileName = picFileName;
    }
    public File getPic() {
        return pic;
    }
    public void setPic(File pic) {
        this.pic = pic;
    }
    public String upload() throws IOException{
        //获得真实路径
        ServletContext sc = ServletActionContext.getServletContext();
        String realPath = sc.getRealPath("/picture");
        //输出文件(将文件拷贝到服务器中项目的目录)
        /*
        *其实就是一个文件拷贝的过程,https://gitee.com/sixiaojie/codes/3ouditmhkznlyjv0efcx731
        *这个链接介绍了通过IO实现的六种拷贝方式,我在这里选择了其中的一种
        */

        FileInputStream fis = new FileInputStream(pic);
        FileOutputStream fos = new FileOutputStream(realPath+"/"+picFileName);
        FileChannel channel1 = fis.getChannel();
        FileChannel channel2 = fos.getChannel();
        channel1.transferTo(0, channel1.size(), channel2);
        channel1.close();
        channel2.close();

        return "upload";
    }
}

第三步:在struts.xml中注册Action

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<package name="test" extends="struts-default" namespace="/test">
    <!-- 文件上传 -->
    <action name="upload" class="demo1.FIleUploadAction" method="upload">
        <result name="upload" type="redirect">/index.jsp</result>
    </action>   
</package>
</struts>

现在其实就可以在页面选择文件,然后保存到服务器了,但是,目前的程序是存在很多问题的,还有很多需要优化的地方,下面开始优化!

优化文件上传程序

  • 上传的文件大小问题,Struts2默认接收上传文件的最大限度为2M;

    文件上传大小的上限是可以修改的,在Struts.xml文件中配置常量,标签为:

    默认的maxSize为2097152,是以字节为单位,也就是2M
    <constant name="struts.multipart.maxSize" value="100000000"></constant>
  • 文件名问题,用户上传文件的文件名可能在服务器端冲突,为了解决这个问题,可以使用UUID生成唯一的名字作为文件名,代码:

    UUID.randomUUID().toString();

    文件名设计为  UUID.后缀,后缀名可以通过接收到的picFileName问价名获取,获取方式:

    String name = UUID.randomUUID().toString()+picFileName.substring(picFileName.lastIndexOf('.'));
  • 文件保存路径问题,保存文件的目录写死在代码中,耦合,不便于维护,解决办法:保存目录名转移到struts.xml配置文件中,在原来基础上使用到一个param标签

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
      "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
      "http://struts.apache.org/dtds/struts-2.3.dtd">

    <struts>
    <package name="test" extends="struts-default" namespace="/test">
      <!-- 文件上传 -->
      <action name="upload" class="demo1.FIleUploadAction" method="upload">
          <param name="filePath">/picture</param>
           <result name="upload" type="redirect">/index.jsp</result>
      </action>   
    </package>
    </struts>

    当浏览器请求name为upload的Action的时候,会自动将param中的值以请求参数的方式发送给Action,这样就可以在Action中接收到“filePath”的值为/picture,同样使用属性名的方式接收

  • 文件拷贝的代码简化,在搭建Struts2开发环境的时候,导入了一些jar包,其中有一个commons-io的jar包,这个jar包中封装拷贝文件的方法:

    FileUtils.copyFile(Pic, new File(picturePath));

    第一个参数为被拷贝的文件对象,第二个参数为拷贝之后的文件对象,picturePath为目标的文件的路径

那么优化之后的Action的文件为

public class FIleUploadAction {
    private File pic;
    private String picFileName;
    private String filePath;

    public String getFilePath() {
        return filePath;
    }
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
    public String getPicFileName() {
        return picFileName;
    }
    public void setPicFileName(String picFileName) {
        this.picFileName = picFileName;
    }
    public File getPic() {
        return pic;
    }
    public void setPic(File pic) {
        this.pic = pic;
    }

    public String upload() throws IOException{
        //获得真实路径
        ServletContext sc = ServletActionContext.getServletContext();
        String realPath = sc.getRealPath(filePath);
        //文件名
        String fileName = UUID.randomUUID().toString()+picFileName.substring(picFileName.lastIndexOf('.'));
        //拷贝输出文件
        FileUtils.copyFile(pic, new File(realPath+"/"+fileName));
        return "upload";
    }
}

下载

当浏览器访问action的时候,action将文件发送到浏览器,供浏览器下载

文件下载相对较为简单,下面为action中的一个方法:

public void download() throws Exception {
        //以这个文件为例,为了演示所以直接给出了文件名
        String fileName = "cc21afb1-88f0-45e4-928e-bb0046aac045.jpg";
        //1. 设置下载信息以文件保存(filename指定文件名)
        //URLEncoder.encode(fileName, "UTF-8"),设置编码格式,否则中文不会显示
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setHeader("content-disposition""attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
        // 1. 读入服务器端文件输入流
        // 路径
        String realPath = ServletActionContext.getServletContext().getRealPath(
                "/upload");
        String filePath = realPath + "/" + fileName;

        //2. 将服务器端要下载文件-----(拷贝到)----》响应输出流
        File srcFile = new File(filePath);
        ServletOutputStream os = response.getOutputStream();
        // 将srcFile文件读入,写出到os对应输出流中。
        // 3. 边读边写。
        FileUtils.copyFile(srcFile, os);
    }

只要浏览器访问该浏览器,浏览器就会将服务器端的文件通过响应输出流发送到浏览器,浏览器就会弹出一个下载框,提示下载该文件。


以上是关于Struts2实现文件的上传与下载的主要内容,如果未能解决你的问题,请参考以下文章

struts2实现文件上传下载

Struts2 实现文件上传和下载

Struts2文件上传与下载

Struts2学习—文件上传和下载

文件上传(多文件上传)/下载

用struts2实现文件的上传下载