struts2实现文件的上传

110 篇文章 6 订阅
36 篇文章 1 订阅

jar包选择

struts2的基础jar包,其实struts2的上传底层还是使用commons-fileupload和commons-io实现的。
这里写图片描述

文件上传的前提

  • 表单method必须是post
  • enctype取值必须是multipart/form-data(默认:application/x-www-form-urlencoded)
  • 提供文件选择域

程序代码

使用了struts2的s标签

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>上传页面</title>
    <s:head/>
  </head>
  <body>
    <s:form action="upload.action" method="post" enctype="multipart/form-data">
        <s:textfield name="username" label="用户名"></s:textfield>
        <s:file name="photo" label="照片"></s:file>
        <s:submit label="上传"></s:submit>
    </s:form>
  </body>
</html>

动作类:

  1. 获取servletContext对象
  2. 首先使用realPath方法根据一个虚拟目录得到一个真实的目录,把上传的文件放在项目的/WEB-INF/upload文件夹里面。
  3. 判断/WEB-INF/upload文件夹是否存在,如果不存在,创建新的文件夹。
  4. 把上传的文件从临时文件(fileupload超过10KB使用磁盘临时文件使用缓存,不足10KB使用内存作为缓存)剪切到/WEB-INF/upload目录下,并重新命名。
public class UploadAction extends ActionSupport {
    //表单上提供的字段
    private String username;
    private File photo;

    private String photoFileName;//上传的文件名。上传的字段名称+filename
    private String photoContentType;//上传的文件MIME类型。上传字段名称+ContentType 


    public String upload(){
        //1.获取servletContext对象
        ServletContext application = ServletActionContext.getServletContext();
        //2.调用realPath方法获取根据一个虚拟目录得到的真实目录
        String filePath=application.getRealPath("/WEB-INF/upload");
        File file=new File(filePath);
        if(!file.exists()){
            file.mkdir();
        }
        photo.renameTo(new File(file,photoFileName));
        return null;
    }
    public File getPhoto() {
        return photo;
    }

    public void setPhoto(File photo) {
        this.photo = photo;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    public String getPhotoFileName() {
        return photoFileName;
    }
    public void setPhotoFileName(String photoFileName) {
        this.photoFileName = photoFileName;
    }
    public String getPhotoContentType() {
        return photoContentType;
    }
    public void setPhotoContentType(String photoContentType) {
        this.photoContentType = photoContentType;
    }
}

struts.xml
仅仅配置了一个upload动作,没有返回结果

 <struts>
    <constant name="struts.devMode" value="true"/>
    <package name="user" extends="struts-default">
        <action name="upload" class="com.scx.web.action.UploadAction" method="upload">
        </action>
    </package>
 </struts>

运行结果

这里写图片描述
我们上传了一个大小为616KB的图片,成功在/WEB-INF/upload文件夹中找到了。
我们能不能上传更大的呢?这次我们选择一个大小为2116KB的图片。
这里写图片描述
好像失败了。
这里写图片描述
这里写图片描述
为什么我们上传616KB的图片成功,上传2116KB的图片就报错呢?

文件上传大小的限制

如果上传文件超过了默认大小,upload拦截器会转向一个input的逻辑视图。
查看default.properties文件,在第71行我们会看到
这里写图片描述
struts限制了我们上传的文件大小为2097152字节(2MB=1024*1024*2)

解决方法

我们可以在struts.xml中改变default.properties文件中的常量。
设置默认的上传文件大小为3MB.
这里写图片描述
再次运行一次:
这里写图片描述
成功的上传了文件。

配置input视图

虽然我们修改了上传的大小范围,但是肯定还有别人上传更大的文件,
我们应该如何修改呢?

为upload动作配置input结果视图,当用户上传了大于限制的文件,再次跳转到上传页面

在upload.jsp页面中添加


    <s:actionerror/>

标签。

这里写图片描述

这里写图片描述

这里写图片描述

限制文件上传的类型

有时候我们需要用户上传指定的类型,例如图片,音乐等。
这个时候我们可以为上传的拦截器(FileUploadInterceptor)注入相关参数来限制用户上传的文件类型。
在FileUploadInterceptor拦截器类中我们会看到这两个参数

这里写图片描述
其中

  • allowedTypeSet是允许上传文件的MIME类型
  • allowedExtensionsSet是允许上传文件的扩展名。
    使用其对应的set方法为其注入参数。
    如果我们要限制用户上传的内容为图片

限制上传文件的扩展名

这里写图片描述
当上传非限定扩展名时:当我们上传了一个txt文档时,有如下错误提示
这里写图片描述

限制上传文件的MIME类型

这里写图片描述
当上传非限定的MIME类型:当我们上传了一个txt文档时,有如下错误提示
这里写图片描述

出错后的中文信息提示

上面上传文件后出错的信息有很多英文,对于用户来说都是很难读懂的,那么如何能够转变为用户能够读懂的信息呢。

解决办法:Struts2中的所有文本提示都是基于国际化的,用国际化消息资源包,把对应的key取值改为中文即可。默认信息提示在:struts2-core.jar\org.apache.struts2\struts-message.properties

配置步骤如下:

  1. 创建新的资源文件,例如fileupload_message.properties.放在src下,在该资源中添加如下信息
    这里写图片描述
  2. 在struts.xml文件中加载该资源文件
    <!-- 配置上传文件的出错信息的资源文件 -->
    <constant name="struts.custom.i18n.resources" value="com.scx.web.action.fileupload_message"></constant>

运行结果:
这里写图片描述

小提示

在文件上传时我们还必须要考虑到一些问题。

  • 保证服务器的安全要把上传的文件上传到客户端无法访问的地方。
  • 用户没有上传的问题
  • 避免文件被覆盖(文件重名问题),让文件名唯一即可
  • 避免 同一个文件夹文件过多
    • 按照日期进行打散存贮目录
    • 用文件名的hashCode计算打散的存储目录:二级目录
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值