前一阵子有些朋友在电子邮件中问关于Struts 2实现文件上传的问题, 所以今天我们就来讨论一下这个问题。
实现原理
Struts 2是通过Commons FileUpload文件上传。Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。从而我们就能够以本地文件方式的操作浏览器上传的文件。
具体实现
前段时间Apache发布了Struts 2.0.6 GA,所以本文的实现是以该版本的Struts作为框架的。以下是例子所依赖类包的列表:
清单1 依赖类包的列表
首先,创建文件上传页面FileUpload.jsp,内容如下:
<%
@ page language
=
"
java
"
contentType
=
"
text/html; charset=utf-8
"
pageEncoding
=
"
utf-8
"
%>
<%
@ taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>
Struts 2 File Upload
title
>
head
>
<
body
>
<
s:form
action
="fileUpload"
method
="POST"
enctype
="multipart/form-data"
>
<
s:file
name
="myFile"
label
="Image File"
/>
<
s:textfield
name
="caption"
label
="Caption"
/>
<
s:submit
/>
s:form
>
body
>
html
>
清单2 FileUpload.jsp
在FileUpload.jsp中,先将表单的提交方式设为POST,然后将enctype设为multipart/form-data,这并没有什么特别之处。接下来,标志将文件上传控件绑定到Action的myFile属性。
其次是FileUploadAction.java代码:
package
tutorial;
import
java.io.BufferedInputStream;
import
java.io.BufferedOutputStream;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.InputStream;
import
java.io.OutputStream;
import
java.util.Date;
import
org.apache.struts2.ServletActionContext;
import
com.opensymphony.xwork2.ActionSupport;
public
class
FileUploadAction
extends
ActionSupport
{
private static final long serialVersionUID = 572146812454l ;
private static final int BUFFER_SIZE = 16 * 1024 ;
private File myFile;
private String contentType;
private String fileName;
private String imageFileName;
private String caption;
public void setMyFileContentType(String contentType) {
this .contentType = contentType;
}
public void setMyFileFileName(String fileName) {
this .fileName = fileName;
}
public void setMyFile(File myFile) {
this .myFile = myFile;
}
public String getImageFileName() {
return imageFileName;
}
public String getCaption() {
return caption;
}
public void setCaption(String caption) {
this .caption = caption;
}
private static void copy(File src, File dst) {
try {
InputStream in = null ;
OutputStream out = null ;
try {
in = new BufferedInputStream( new FileInputStream(src), BUFFER_SIZE);
out = new BufferedOutputStream( new FileOutputStream(dst), BUFFER_SIZE);
byte [] buffer = new byte [BUFFER_SIZE];
while (in.read(buffer) > 0 ) {
out.write(buffer);
}
} finally {
if ( null != in) {
in.close();
}
if ( null != out) {
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getExtention(String fileName) {
int pos = fileName.lastIndexOf( " . " );
return fileName.substring(pos);
}
@Override
public String execute() {
imageFileName = new Date().getTime() + getExtention(fileName);
File imageFile = new File(ServletActionContext.getServletContext().getRealPath( " /UploadImages " ) + " / " + imageFileName);
copy(myFile, imageFile);
return SUCCESS;
}
}
清单3 tutorial/FileUploadAction.java
在FileUploadAction中我分别写了setMyFileContentType、setMyFileFileName、setMyFile和setCaption四个Setter方法,后两者很容易明白,分别对应FileUpload.jsp中的和标志。但是前两者并没有显式地与任何的页面标志绑定,那么它们的值又是从何而来的呢?其实,标志不仅仅是绑定到myFile,还有myFileContentType(上传文件的MIME类型)和myFileFileName(上传文件的文件名,该文件名不包括文件的路径)。因此,对应Action类里面的xxx、xxxContentType和xxxFileName三个属性。
FileUploadAction作用是将浏览器上传的文件拷贝到WEB应用程序的UploadImages文件夹下,新文件的名称是由系统时间与上传文件的后缀组成,该名称将被赋给imageFileName属性,以便上传成功的跳转页面使用。
下面我们就来看看上传成功的页面:
<%
@ page language
=
"
java
"
contentType
=
"
text/html; charset=utf-8
"
pageEncoding
=
"
utf-8
"
%>
<%
@ taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>
Struts 2 File Upload
title
>
head
>
<
body
>
<
div
style
="padding: 3px; border: solid 1px #cccccc; text-align: center"
>
<
img
src
='UploadImages/
value
="imageFileName"
/>
' />
<
br
/>
<
s:property
value
="caption"
/>
div
>
body
>
html
>
清单4 ShowUpload.jsp
ShowUpload.jsp获得imageFileName,将其UploadImages组成URL,从而将上传的图像显示出来。
然后是Action的配置文件:
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
="fileUploadDemo"
extends
="struts-default"
>
<
action
name
="fileUpload"
class
="tutorial.FileUploadAction"
>
<
interceptor-ref
name
="fileUploadStack"
/>
<
result
name
="success"
>
/ShowUpload.jsp
result
>
action
>
package
>
struts
>
清单5 struts.xml
fileUpload Action显式地应用fileUploadStack的拦截器。
最后是web.xml配置文件:
xml version="1.0" encoding="UTF-8"
?>
<
web-app
id
="WebApp_9"
version
="2.4"
xmlns
="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
<
display-name
>
Struts 2 Fileupload
display-name
>
<
filter
>
<
filter-name
>
struts-cleanup
filter-name
>
<
filter-class
>
org.apache.struts2.dispatcher.ActionContextCleanUp
filter-class
>
filter
>
<
filter
>
<
filter-name
>
struts2
filter-name
>
<
filter-class
>
org.apache.struts2.dispatcher.FilterDispatcher
filter-class
>
filter
>
<
filter-mapping
>
<
filter-name
>
struts-cleanup
filter-name
>
<
url-pattern
>
/*
url-pattern
>
filter-mapping
>
<
filter-mapping
>
<
filter-name
>
struts2
filter-name
>
<
url-pattern
>
/*
url-pattern
>
filter-mapping
>
<
welcome-file-list
>
<
welcome-file
>
index.html
welcome-file
>
welcome-file-list
>
web-app
>
清单6 WEB-INF/web.xml
发布运行应用程序,在浏览器地址栏中键入:http://localhost:8080/Struts2_Fileupload/FileUpload.jsp,出现图示页面:
清单7 FileUpload页面
选择图片文件,填写Caption并按下Submit按钮提交,出现图示页面:
清单8 上传成功页面
更多配置
在运行上述例子,如果您留心一点的话,应该会发现服务器控制台有如下输出:
Mar
20
,
2007
4
:
08
:
43
PM org.apache.struts2.dispatcher.Dispatcher getSaveDir
INFO: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
Mar
20
,
2007
4
:
08
:
43
PM org.apache.struts2.interceptor.FileUploadInterceptor intercept
INFO: Removing file myFile C:/Program Files/Tomcat
5.5
/work/Catalina/localhost/Struts2_Fileupload/upload_251447c2_1116e355841__7ff7_00000006.tmp
清单9 服务器控制台输出
上述信息告诉我们,struts.multipart.saveDir没有配置。struts.multipart.saveDir用于指定存放临时文件的文件夹,该配置写在struts.properties文件中。例如,如果在struts.properties文件加入如下代码:
struts.multipart.saveDir
=
/tmp
清单10 struts配置
这样上传的文件就会临时保存到你根目录下的tmp文件夹中(一般为c:/tmp),如果此文件夹不存在,Struts 2会自动创建一个。
错误处理
上述例子实现的图片上传的功能,所以应该阻止用户上传非图片类型的文件。在Struts 2中如何实现这点呢?其实这也很简单,对上述例子作如下修改即可。
首先修改FileUpload.jsp,在
与
之间加入“”,用于在页面上输出错误信息。
然后修改struts.xml文件,将Action fileUpload的定义改为如下所示:
<
action
name
="fileUpload"
class
="tutorial.FileUploadAction"
>
<
interceptor-ref
name
="fileUpload"
>
<
param
name
="allowedTypes"
>
image/bmp,image/png,image/gif,image/jpeg
param
>
interceptor-ref
>
<
interceptor-ref
name
="defaultStack"
/>
<
result
name
="input"
>
/FileUpload.jsp
result
>
<
result
name
="success"
>
/ShowUpload.jsp
result
>
action
>
清单11 修改后的配置文件
显而易见,起作用就是fileUpload拦截器的allowTypes参数。另外,配置还引入defaultStack它会帮我们添加验证等功能,所以在出错之后会跳转到名称为“input”的结果,也即是FileUpload.jsp。
发布运行应用程序,出错时,页面如下图所示:
清单12 出错提示页面
上面的出错提示是Struts 2默认的,大多数情况下,我们都需要自定义和国际化这些信息。通过在全局的国际资源文件中加入“struts.messages.error.content.type.not.allowed=The file you uploaded is not a image”,可以实现以上提及的需求。对此有疑问的朋友可以参考我之前的文章《在Struts 2.0中国际化(i18n)您的应用程序》。
实现之后的出错页面如下图所示:
清单13 自定义出错提示页面
同样的做法,你可以使用参数“maximumSize”来限制上传文件的大小,它对应的字符资源名为:“struts.messages.error.file.too.large”。
字符资源“struts.messages.error.uploading”用提示一般的上传出错信息。
多文件上传
与单文件上传相似,Struts 2实现多文件上传也很简单。你可以将多个绑定Action的数组或列表。如下例所示。
<
s:form
action
="doMultipleUploadUsingList"
method
="POST"
enctype
="multipart/form-data"
>
<
s:file
label
="File (1)"
name
="upload"
/>
<
s:file
label
="File (2)"
name
="upload"
/>
<
s:file
label
="FIle (3)"
name
="upload"
/>
<
s:submit
/>
s:form
>
清单14 多文件上传JSP代码片段
如果你希望绑定到数组,Action的代码应类似:
private
File[] uploads;
private
String[] uploadFileNames;
private
String[] uploadContentTypes;
public
File[] getUpload()
{ return this .uploads; }
public
void
setUpload(File[] upload)
{ this .uploads = upload; }
public
String[] getUploadFileName()
{ return this .uploadFileNames; }
public
void
setUploadFileName(String[] uploadFileName)
{ this .uploadFileNames = uploadFileName; }
public
String[] getUploadContentType()
{ return this .uploadContentTypes; }
public
void
setUploadContentType(String[] uploadContentType)
{ this .uploadContentTypes = uploadContentType; }
清单15 多文件上传数组绑定Action代码片段
如果你想绑定到列表,则应类似:
private
List
<
File
>
uploads
=
new
ArrayList
<
File
>
();
private
List
<
String
>
uploadFileNames
=
new
ArrayList
<
String
>
();
private
List
<
String
>
uploadContentTypes
=
new
ArrayList
<
String
>
();
public
List
<
File
>
getUpload()
{
return this .uploads;
}
public
void
setUpload(List
<
File
>
uploads)
{
this .uploads = uploads;
}
public
List
<
String
>
getUploadFileName()
{
return this .uploadFileNames;
}
public
void
setUploadFileName(List
<
String
>
uploadFileNames)
{
this .uploadFileNames = uploadFileNames;
}
public
List
<
String
>
getUploadContentType()
{
return this .uploadContentTypes;
}
public
void
setUploadContentType(List
<
String
>
contentTypes)
{
this .uploadContentTypes = contentTypes;
}
清单16 多文件上传列表绑定Action代码片段
总结
在Struts 2中实现文件上传的确是轻而易举,您要做的只是使用与Action的属性绑定。这又一次有力地证明了Struts 2的简单易用。
posted on 2007-03-21 00:48
Max 阅读(12059)
评论(82)
编辑
收藏 所属分类:
Struts 2.0系列
评论:
# re: 在Struts 2中实现文件上传 2007-03-21 16:33 | 大菜虫
max大大我现在刚开始学习Struts 2.0.6按照您在Struts 2.0系列之一里的方法去做可是生成war文件上传到tomcat上,tomcat启动都报错,我用的是zip的tomcat5.5.23。我发现在Struts 2.0.6中没有struts2-api.jar这个文件。是tomcat配置出了问题。还是没有struts2-api.jar这个文件的原因。
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-21 16:39 |
山风小子
您写的Struts2系列很详尽,在此表示感谢!
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-22 09:27 |
太阳里的雪
不错的资料,Struts2本来就是Webwork的后续版本,学了Webwork就等于学习了Struts2.
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-23 09:15 | yangdamao
請問如何查看服务器控制台输出?----多多指教
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-23 09:54 |
Max
@yangdamao
不同服务器,有不同的方法,建议通过IDE启动服务器,这样可以在IDE的控制台查看输出。
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-23 11:39 | yangdamao
我用的是tomcat6.0,麻煩詳細描述一下,這方面的知識嚴重欠缺,tks!
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-03-23 17:16 | evan
呵呵!能不能写一个struts2 ajax方面的啊?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-27 08:16 | jintian
javax.servlet.ServletException: String index out of range: -1
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:518)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:421)
org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)
這是啥錯誤??
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-28 08:13 | jintian
在struts.xml為什么不要
引入< include file ="struts-default.xml" /> ﹗
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-03-28 09:35 |
A++
@jintian
我昨天也碰到了这个问题
你可以试着把public String execute()中的空格去掉
方法是查找替换~~-:)
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-04-03 14:22 | Michael
我在上传文件的时候提示我
com.opensymphony.xwork2.config.ConfigurationException: Unable to load bean
org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta)
只要把里的 enctype ="multipart/form-data"去掉就不出这个提示了。请问这是怎么回是呢?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-05 11:54 | ccz
估计是你少加了类包!特别是那个IO的
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-09 22:30 | eddie
请问在哪里加入struts.messages.error.content.type.not.allowed=The file you uploaded is not a image,我试过很多地方都不行
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-09 22:36 | eddie
struts.messages.error.content.type.not.allowed=The file you uploaded is not a image 后来在全局文件global_message.properties里面添加成功了,但是为什么在package.properties里面不行呢
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-09 23:26 |
Max
@eddie
这是因为GetText()方法是在org.apache.struts2.interceptor.FileUploadInterceptor类中被调用,而不是在你的Action类的验证方法中被调用。
代码如下:
private String getTextMessage(String messageKey, Object[] args, Locale locale) {
if (args == null || args.length == 0) {
return LocalizedTextUtil.findText(this.getClass(), messageKey, locale);
} else {
return LocalizedTextUtil.findText(this.getClass(), messageKey, locale, DEFAULT_MESSAGE, args);
}
}
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-10 10:08 | furong
我想问一下,下载包中的lib文件夹中没有commons-fileupload-1.1.1.jar
commons-io-1.1.jar这两个包,那这两个包是不是要专门下啊
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-10 23:08 |
Max
@furong
是的,到APACHE下载!
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-25 16:26 | ddd
@大菜虫
跟struts-api.jar没有关系, 2.06版的没有api包了,2.05有。。
估计是你其他地方配置有问题,你在本地Server上运行没有问题吗?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-04-25 16:27 | ddd
@evan
请参考这里。。
http://struts.apache.org/2.x/docs/tutorials.html
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-04-26 16:33 | Z
请问如何在struts.properties文件里用struts.multipart.maxSize对不同的上载限制不同的大小啊?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-02 14:04 |
杰克
在对多文件上传进行格式验证时,由于文件同名,在报错时发生一人犯错全家株连的问题,这个问题该怎么办呢?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-10 08:48 | satanxm
请问用ajax 该怎么样上传文件呢,
我把你的例子中的程序 中的 form 和 submit 该为theme 改为 ajax
就是不能用,目标div上出来个 [HTMLobject ]
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-15 12:46 |
pengzhan
有没有关于下载的东东???
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-19 11:43 | zy
上传的jsp编码似乎一定要设置成"UTF-8",GBK的话就不行了。
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-24 11:14 |
文温
我的struts使用的gbk编码
提交时经常出现,再刷新能显示正常,请问怎么使用gbk编码上传文件
javax.servlet.ServletException
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:518)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:421)
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-24 11:43 |
文温
对不起了
我没有在web.xml文件中增加过滤器
< filter >
< filter-name > struts-cleanup filter-name >
< filter-class >
org.apache.struts2.dispatcher.ActionContextCleanUp
filter-class >
filter >
能帮忙解释一下这个过滤器的作用是什么吗?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-25 10:29 |
Max
@文温
By adding this filter, the FilterDispatcher will know to not clean up and instead defer cleanup to this filter.
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-05-28 19:00 | gpiaofei2006
org.apache.struts2.ServletActionContext 在哪个包里啊,我的无法import
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-06-20 17:03 | jpma
@gpiaofei2006
在struts2-core-2.0.6.jar中!
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-06-27 10:27 |
[email protected]
HTTP Status 404 - /uploadfile/FileUpload
--------------------------------------------------------------------------------
type Status report
message /uploadfile/FileUpload
description The requested resource (/uploadfile/FileUpload) is not available.
为什么我按照你出现上面这个错误??????谁能帮忙回答下
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-03 10:12 | carlos175
一运行就会出现这个问题是怎么回事呢?
HTTP ERROR: 500
Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]
RequestURI=/webapps/upload/fileUpload
Caused by:
java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]
把enctype ="multipart/form-data"去掉后就会出现:
HTTP ERROR: 404
NOT_FOUND
RequestURI=/webapps/upload/fileUpload
但是说enctype ="multipart/form-data" 这个是必须的~
貌似是无法加载MultiPartRequest这个东西。应该如何解决呢?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-03 12:03 | trying
使用这个代码的时候总是出现:
HTTP ERROR: 404
NOT_FOUND
RequestURI=/webapps/upload/fileUpload
这个错误。是怎么回事呢?
P.S:LS的只要导入commons-io那个jar就可以解问题。
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-04 22:49 |
Max
@carlos175
@trying
是否缺少某些包?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-06 12:25 | carlos175
问题已经都解决了。
多谢Max的这篇文章。感觉写的很不错。
这周刚刚开始使用struts2。感觉和struts1.2差别还是挺大的。刚刚开始写有点不适应。
特别是昨天在写表单处理的时候感觉布局上就变了。
一个标签就一行。如果我在标签中加入了theme属性的话那么就可以解决。
恩,希望Max能够给出一篇介绍struts2标签使用比较详细的文章。再次感谢你提供了这篇不错的文章。
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-07-16 11:35 | Joe
@A++
我也遇到该问题,我试了你说的方法,还是报错java.lang.StringIndexOutOfBoundsException: String index out of range: -1
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-27 14:39 |
renminyan
HTTP Status 500 -
-----------------------------------
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]
com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:136)
com.opensymphony.xwork2.inject.ContainerImpl.getInstance(ContainerImpl.java:476)
com.opensymphony.xwork2.inject.ContainerImpl.getInstance(ContainerImpl.java:486)
com.opensymphony.xwork2.inject.ContainerImpl$9.call(ContainerImpl.java:517)
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:542)
com.opensymphony.xwork2.inject.ContainerImpl.getInstance(ContainerImpl.java:515)
org.apache.struts2.dispatcher.Dispatcher.wrapRequest(Dispatcher.java:700)
org.apache.struts2.dispatcher.FilterDispatcher.prepareDispatcherAndWrapRequest(FilterDispatcher.java:330)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:390)
org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)
note The full stack trace of the root cause is available in the Apache Tomcat/5.5.20 logs.
Apache Tomcat/5.5.20
为什么我每个例子多要调半天才出来呢?
技术不到家max帮帮忙?希望自己快点长进~~~~~~~
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-07-31 12:03 | Allen
感觉写的8错。有点相见恨晚的感觉^_^,但是我有几个地方8懂,请指教。
上传文件最大是多大?
上传的进度究竟怎么查看?
你只列出了Image的,那么我控制别的格式的文件上传呢?比如说zip和XML文件
如果文件忒大,我是否可以在上传之前就终止上传,太大的话Struts2好像是直接抛一个错误。
struts2最大可以上传多大的文件,我听说好像只有30Mの
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-31 23:19 |
Max
@renminyan
请细心对照我文中的步骤去做,结果应该会出来的。
或者你的WEB-INF/web.xml的内容,是否有加入:
< filter >
< filter-name > struts2 filter-name >
< filter-class >
org.apache.struts2.dispatcher.FilterDispatcher
filter-class >
filter >
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-07-31 23:32 |
Max
@Allen
1、你可以使用参数“maximumSize”来限制上传文件的大小,它默认值是2mb;
2、上传进度需要使用AJAX技术实现,具体你可以Google一下Ajax File Upload;
3、你可以查看一下zip和xml的MIME类型,如果我记错的啊应该分别是application/zip和text/xml;
4、太大的文件,不建议使用HTTP的上传,可以使用专门的FTP或者其它协议。
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-08-02 16:17 | Allen
@Max
谢谢MAX的解答
1.我已经把他设置到30M了,但是客户如果而已上传大文件的话还是不能捕获异常,就让他抛出异常吧…………
2.Ajax Fileupload这个我会了。但是Ajax+Struts2实现我就8会了……因为Struts2包装的太严实了,我都无从下手的感觉。它好像直接在setter方法前边就把他搞定了。但是setter是在execute方法之前执行的……所以要在execute里边实现这个东西貌似不太现实。
是否利用拦截器可以呢?所以就这个问题我希望方便的话可否解答下。感谢!
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-08-09 11:44 | james
上传文件好像不能用modelDriven模式,感觉有点不太舒服
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-08-15 14:51 | baekham
文件上传fileUpload拦截器allowedTypes设置疑问?
image/bmp,image/png,image/gif,image/jpeg
为什么png、jpeg类型的图片不能上传,提示上传文件格式错误.
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-08-15 22:15 |
王佳
如果在一个信息编辑页面
上传图片只是其中一个字段
但图片已经上传
而我只是需要修改其他信息的时候
这个时候,修改就会不能通过。
Content-Type not allowed: myFile "upload_4e0e6f19_113d55eebb4__8000_00000007.tmp" application/octet-stream
请问:有什么好的解决办法?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-08-16 13:32 | zhw
上传时指定文件大小后
上传文件超过指定大小,就不能再次打开上传页面。报下面的错误:
Struts Problem Report
Struts has detected an unhandled exception:
Messages: No result defined for action com.superweb.web.action.ResideAction and result input
File: file:/D:/Eclipse/eclipse/workspace/SuperWeb/WebRoot/WEB-INF/classes/struts/struts_reside.xml
Line number: 25
Column number: 70
只能重新启动服务器
我用的是spring2+hibernate3+struts2
请问:如何解决?
dwr+struts1.2可以实现上传进度条,请问在struts2中如何实现的?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-08-17 12:56 | babala
Max,
在
image/png,image/bmp,image/gif,image/jpeg,image/jpg
中,只有bmp与gif格式可以上传,其他三个都说格式不正确,这是为什么?
另外为什么不直接使用png,bmp,gif....这种格式,而要在前面加上个image?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-08-27 18:15 | libinbin
回楼上 image/jpg 改成 image/JPG 就行了
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-08-29 13:50 | Ouch
好像还应该加入包servlet-api.jar !!!
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-03 16:58 | li
好像filename取出来的是null呀,有人碰到这种情况吗?
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-09-04 09:40 | Mike
我取出来的filename也是null啊,到底怎么搞的,有些地方没有讲清楚
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-04 16:13 | tf
我取出的也是null,
运行出现下面的错误提示,也就是值都没有传过去.请高手指教
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
java.lang.NullPointerException
tutorial.FileUpload.getExtention(FileUpload.java:76)
tutorial.FileUpload.execute(FileUpload.java:82)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:334)
com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:221)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:195)
com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.intercept(ParametersInterceptor.java:118)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
com.opensymphony.xwork2.interceptor.PrepareInterceptor.intercept(PrepareInterceptor.java:115)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:155)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:180)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:204)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
org.apache.struts2.impl.StrutsActionProxy$1.call(StrutsActionProxy.java:25)
org.apache.struts2.impl.StrutsActionProxy$1.call(StrutsActionProxy.java:24)
org.apache.struts2.impl.RequestContextImpl.callInContext(RequestContextImpl.java:147)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:23)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:317)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:242)
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-04 17:03 | tf
怎么没有人回答?请高手指教
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-05 00:35 |
Max
@Mike
@tf
请细心对照我文中的步骤去做,结果应该会出来的。
或者你的WEB-INF/web.xml的内容,是否有加入:
< filter >
< filter-name > struts2 filter-name >
< filter-class >
org.apache.struts2.dispatcher.FilterDispatcher
filter-class >
filter >
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-09-07 15:59 | Mike
@li
@tf
我想我大概知道错误的原因了,你们可能是漏了一些get/set方法,或者是自己在struts.xml中加入了,这个不需要自己加入的,是struts2内置的interceptor,会自动调用。我希望我的解决方法可以对你们有用,这里也要对max说声对不起了,没有跑出来是自己没按照规则来做。
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-10 16:59 | tf
请问Max可以出个和文件上传对应的文件下载的例子吗?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-10 17:09 | tf
# re: 在Struts 2中实现文件上传 2007-09-12 15:53 | shenchong
Max,请问一下为什么我在做多附件上传的时候uploads里面的内容是String型的,而不是File类型的
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-13 00:19 |
Max
@tf
Struts 2 的Show Case中有相关的例子
@shenchong
你看错了吧?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-13 11:04 | laibin
学习中!
在此感谢Max!
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-13 17:46 | shenchong
@Max
我没有看错的,我试过了show case中的相关例子,它拿到的的确是List类型的,但我拿到的却是String的,是不是还需要在哪里配置?或者是jar包的版本问题?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-09-14 09:53 |
ILOVEYOU
# re: 在Struts 2中实现文件上传 2007-09-14 22:34 | leson
提醒一下,MAX示例代码中拷贝文件部分:
in = new BufferedInputStream( new FileInputStream(src), BUFFER_SIZE);
out = new BufferedOutputStream( new FileOutputStream(dst), BUFFER_SIZE);
byte [] buffer = new byte [BUFFER_SIZE];
while (in.read(buffer) > 0 ) {
out.write(buffer);
}
有点问题,如果文件的大小,%BUFFERSIZE的余数不为0,则会造成多拷贝了N多K字节,又加之buffer[]里面剩余部分没有被覆盖,导致最后的文件和原来的文件前面部分相等,后面的部分就没有多少规律了,但却又不是全空。
修正方法是:
byte[] buffer = new byte[BUFFER_SIZE];
for (int byteRead = 0; (byteRead = in.read(buffer)) > 0; )
{
out.write(buffer, 0, byteRead);
}
最后一次写入该写的字节就可以了。
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-09-26 22:14 | Jimmy
文件类型里明明有jpeg,png的,为什么不能上传?
Content-Type not allowed: myFile "upload_3eb7e010_115421d641d__8000_00000032.tmp" image/pjpeg
Content-Type not allowed: myFile "upload_3eb7e010_115421d641d__8000_00000034.tmp" image/x-png
回复
更多评论
# 遇到了同样的问题 2007-10-09 12:00 | referee
上面有人出现的问题我也遇到了,搞不来,哪位高人帮帮忙
java.io.FileNotFoundException: F:/cvs_root/struts/WebContent/UploadImages/1191902350707.bmp (系统找不到指定的路径。)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(Unknown Source)
at java.io.FileOutputStream.(Unknown Source)
at tutorial.FileUploadAction.copy(FileUploadAction.java:55)
at tutorial.FileUploadAction.execute(FileUploadAction.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:334)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:195)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.intercept(ParametersInterceptor.java:118)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.intercept(PrepareInterceptor.java:115)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:155)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:180)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:266)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:193)
at org.apache.struts2.impl.StrutsActionProxy$1.call(StrutsActionProxy.java:25)
at org.apache.struts2.impl.StrutsActionProxy$1.call(StrutsActionProxy.java:24)
at org.apache.struts2.impl.RequestContextImpl.callInContext(RequestContextImpl.java:147)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:23)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:317)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:242)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Unknown Source)
2007-10-9 11:59:10 org.apache.struts2.interceptor.FileUploadInterceptor intercept
信息: Removing file myFile /tmp/upload__7d878dc9_11582e8d4f6__8000_00000002.tmp
回复
更多评论
# 知道答案了 2007-10-09 12:43 | referee
是文件夹要手动建立
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-10-10 12:42 | hehe
不错,什么时候来个struts2+hibernate+spring整合,期待中。。。。。。。。
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-10-31 16:57 |
赫连紫軒(puras)
Struts2.0的上传文件大小默认是2M
可以通过在struts.xml里来修改这个大小
但是遇到个问题就是
这里假如我设置的是5M
而我的Action实上设置的为3M
此时我上传4M的文件的时候
可以捕捉到异常提示我文件过大
返回到上传页面
如果此时我上传的文件超过了5M
则会直接告诉我文件过大
虽然也会返回到上传页面
但之前上传页面的数据将会丢失
比如说从别的页面传递过来的一些参数.
请教下该如何解决?
谢谢.
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-01 10:27 | 游客
max你好,我一直关注着你的struts2,从开始接触struts2就是看的你的博客,受益匪浅,非常感谢你的介绍,现在网上关于struts的内容太少了。你说的批量上传文件,他的文件名里有系统时间,那同一次上传的文件,系统时间是一样的吗
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-23 11:07 | kayata
@游客
遇到一个问题,struts2和spring2集成后,在文件上传时,发现fileload拦截器不工作,设置的文件类型和大小都不起作用,不知为什么?,急
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-26 09:35 |
@游客
点击文件上传时提示Invalid field value for field "myFile",你的myFile字段时File型,我把他改成String型就可以,然后做相应的修改,请问这到底时为何
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-29 09:16 | bolly
我在上传的action中加了拦截器以后,别的action请求也被拦截下来了,fileUpload是全局的吗?怎么解决?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-29 09:37 | bolly
method="dofileUpload">
application/vnd.ms-excel,text/plain
WEB-INF/jsp/zzz/upload.jsp
WEB-INF/jsp/zzz/upload.jsp
method="uploadClear">
WEB-INF/jsp/zzz/upload.jsp
WEB-INF/jsp/zzz/upload.jsp
uploadClear提交不到action中去,怎么会这样?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-29 10:15 | zoninge
大家帮我看看这个错误啊,包已经添进去了,怎么回事呢?
HTTP Status 404 - /photo/fileUpload
--------------------------------------------------------------------------------
type Status report
message /photo/fileUpload
description The requested resource (/photo/fileUpload) is not available.
--------------------------------------------------------------------------------
Apache Tomcat/5.5.15
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-11-29 17:38 | zoninge
终于出来了
相当感谢啊
我是小菜鸟 多多指教!
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-12-22 09:59 | xtmtd
上传一个大文件时,STRUTS2的拦截器,会报错,说文件过大。但是一次上传几个大文件时,STRUTS2的拦截器就不报任何错误了,也没有提示,不知道为什么啊?
回复
更多评论
# re: 在Struts 2中实现文件上传 2007-12-26 10:14 | suyuan
啊 我也出现了这个问题
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]
com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:136)
com.opensymphony.xwork2.inject.ContainerImpl.getInstance(ContainerImpl.java:476)
com.opensymphony.xwork2.inject.ContainerImpl.getInstance(ContainerImpl.java:486)
com.opensymphony.xwork2.inject.ContainerImpl$9.call(ContainerImpl.java:517)
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:542)
com.opensymphony.xwork2.inject.ContainerImpl.getInstance(ContainerImpl.java:515)
org.apache.struts2.dispatcher.Dispatcher.wrapRequest(Dispatcher.java:697)
org.apache.struts2.dispatcher.FilterDispatcher.prepareDispatcherAndWrapRequest(FilterDispatcher.java:330)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:390)
org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)
note The full stack trace of the root cause is available in the Apache Tomcat/5.5.23 logs.
filter 也配了 上传出现这个,。。。。
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-12-29 10:20 | wendy
这么写会存在并发问题吧?
回复
更多评论
# re: 在Struts 2中实现文件上传[未登录] 2007-12-29 21:56 | wendy
当我上传一个空文件时(比如说我建一个 新建文件.txt),报空指针异常,我觉得只要文件存在不管里面有没有内容都不应该报错的啊,为什么?
回复
更多评论
# re: 在Struts 2中实现文件上传 2008-01-04 18:03 |
ElgooG
写的东西不完全对啊
回复
更多评论
# re: 在Struts 2中实现文件上传 2008-01-09 20:15 | szz
我想问一下,我的form中加了enctype="multipart/form-data",配了struts2的校验器校验其他的文本框就不起作用了,去了enctype="multipart/form-data",校验器就好用了,这是怎么回事呀?
回复
更多评论
# re: 在Struts 2中实现文件上传 2008-01-22 01:01 | 飞飞
当我配置web.xml后,网站目录不能浏览,出现404错误!
请问这是什么问题?
谢谢.
回复
更多评论
# re: 在Struts 2中实现文件上传 2008-02-20 16:11 | walkerstar
Struts2的文件上传只能说是简单的文件上传。
如果一个网站文件上传很重要的话,需要仔细的考虑各种可能性。
回复
更多评论
# re: 在Struts 2中实现文件上传 2008-02-22 13:10 | look
我无法通过拦截器控制上传类型,代码在下面,有谁能帮我看看,我试了很久fileUploadStack这个拦截器就是不起作用,什么文件都能上传。
struts.xml:
image/bmp,image/png,image/gif,image/jpeg
/upload.jsp
/show.jsp
upload.jsp: