微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java中Struts2文件上传问题详解

文件上传文件下载是我们在web应用程序中常用的两个功能,在java中,实现这两种功能的方式也有很多种,其中struts2就给我们提供了一种算是比较简单的方式吧,下面我们就一起来看一下,

首先是网页部分,upload_file.jsp

Upload File

上传文件的表单,metho必须设置成post,enctype必须设置成multipart/form-data。

从上面代码中可以看到这个表单提交给了UploadFile这个action来处理,那我们在struts.xml里面配置如下:

/uploadResult.jsp20971520

fileUpload拦截器,用于设置上传路径,限制文件类型和大小。

关于限制文件大小,光有是不行的,还必须在标签添加

这行代码表示整个项目所有要上传文件的地方允许上传文件大小的最大值,也就是说这个项目里上传的任何单个文件大小不能超过21000000字节(约20M),如果项目中不添加这行代码,则认允许上传文件大小最大为2M,所以这也是突破struts2只能上传2M文件的限制的方法

关于限制文件类型,如果需要限制为图片文件,则可以这样配置

image/bmp, image/x-png, image/gif, image/jpeg

标签中的值都是文件的MIME类型,常用文件的MIME类型可以在%TOMCAT_HOME%confweb.xml中找到。

如果要限制为word文件,则可以可以这样配置

application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document

然而我感觉这样来限制文件类型,不如用javascript在前端实现限制。

接下来写UploadAction,UploadAction必需的私有属性是source,这是和upload_file.jsp里面文件域的name属性是一致,就是说文件域的name属性值为source,则UploadAction中必需有私有属性source,另外,还有两个比较重要的私有属性

private String sourceFileName; //待上传文件文件

private String sourceContentType; //待上传文件文件类型

这两个变量名的格式就是前面的前缀source和upload_file.jsp中的文件域的name属性相同。

综合来说,就是,比如upload_file.jsp中文件域的name = “abc”,则Action中就需要这样定义

private File abc; private String abcFileName; private String abcContentType;

abc会自动获取上传文件对象,abcFileName自动获取文件名,abcContentType自动获取文件类型。

关于上传路径,是我要重点说一下的。

如果是上传绝对路径,那还挺好搞的,但如果要上传到项目根目录下的upload文件夹呢,怎么获得这个upload文件夹的完整路径?

我尝试过使用

ServletActionContext.getServletContext().getRealPath("/upload");

但返回了null。也用过

ServletActionContext.getRequest().getRealPath("/upload");

还是返回了null。但在网上查下这个问题,很多人都推荐这么写,证明可能某些情况下这样写确实是可行的,但也有跟我一样返回null的人,他们同时推荐了一种新的方法,就是让UploadAction实现ServletContextAware接口。具体做法如下:

public class UploadAction extends ActionSupport implements ServletContextAware { /** * 省略其它代码... */ private ServletContext context; public ServletContext getContext() { return context; } public void setContext(ServletContext context) { this.context = context; } @Override public void setServletContext(ServletContext context) { this.context = context; } }

然后使用

String path = context.getRealPath("/upload");// 重要:斜杠不能少

获得upload文件夹的路径。然后执行上传

/*将文件上传到upload文件夹下*/ File savefile = new File(path, sourceFileName); FileUtils.copyFile(source, savefile);

我个人是比较推荐这种方法的,因为这种方法好像规避了当项目被打包转移到其它环境时也能保证获得正确的路径。

后面贴上UploadAction的完整代码UploadAction.java

package com.lidi.action; import java.io.File; import java.io.IOException; import javax.servlet.ServletContext; import org.apache.commons.io.FileUtils; import org.apache.struts2.util.ServletContextAware; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport implements ServletContextAware { /** * */ private static final long serialVersionUID = 1L; private File source;// 待上传文件 private String sourceFileName;// 待上传文件文件名 private String sourceContentType; // 待上传文件文件类型 private ServletContext context; // 重要 /* 重要 */ public ServletContext getContext() { return context; } public void setContext(ServletContext context) { this.context = context; } /* getters & setters */ public File getSource() { return source; } public void setSource(File source) { this.source = source; } public String getSourceFileName() { return sourceFileName; } public void setSourceFileName(String sourceFileName) { this.sourceFileName = sourceFileName; } public String getSourceContentType() { return sourceContentType; } public void setSourceContentType(String sourceContentType) { this.sourceContentType = sourceContentType; } @Override public void setServletContext(ServletContext context) { this.context = context; } public String execute() throws IOException { /*获取存放上传文件的路径:项目根目录upload文件夹*/ String path; path = context.getRealPath("/upload");// 重要:斜杠不能少 System.out.println(path); /*将文件上传到upload文件夹下*/ File savefile = new File(path, sourceFileName); FileUtils.copyFile(source, savefile); System.out.println(savefile.getAbsolutePath()); return SUCCESS; } }

上传结果页uploadResult.jsp

Upload Result文件名:

文件类型:

文件:">

以上所述就是本文的全部内容了,希望大家能够喜欢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐