前一阵子有些朋友在电子邮件中问关于Struts 2实现文件上传的问题, 所以今天我们就来讨论一下这个问题。
实现原理
Struts 2是通过Commons FileUpload文件上传。Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。从而我们就能够以本地文件方式的操作浏览器上传的文件。
具体实现
前段时间Apache发布了Struts 2.0.6 GA,所以本文的实现是以该版本的Struts作为框架的。以下是例子所依赖类包的列表:
清单1 依赖类包的列表
首先,创建文件上传页面FileUpload.jsp,内容如下:
<% @ 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 >
在FileUpload.jsp中,先将表单的提交方式设为POST,然后将enctype设为multipart/form-data,这并没有什么特别之处。接下来,<s:file/>标志将文件上传控件绑定到Action的myFile属性。
其次是FileUploadAction.java代码:
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;
}
}
在FileUploadAction中我分别写了setMyFileContentType、setMyFileFileName、setMyFile和setCaption四个Setter方法,后两者很容易明白,分别对应FileUpload.jsp中的<s:file/>和<s:textfield/>标志。但是前两者并没有显式地与任何的页面标志绑定,那么它们的值又是从何而来的呢?其实,<s:file/>标志不仅仅是绑定到myFile,还有myFileContentType(上传文件的MIME类型)和myFileFileName(上传文件的文件名,该文件名不包括文件的路径)。因此,<s:file name="xxx" />对应Action类里面的xxx、xxxContentType和xxxFileName三个属性。
FileUploadAction作用是将浏览器上传的文件拷贝到WEB应用程序的UploadImages文件夹下,新文件的名称是由系统时间与上传文件的后缀组成,该名称将被赋给imageFileName属性,以便上传成功的跳转页面使用。
下面我们就来看看上传成功的页面:
<% @ 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/<s:property value ="imageFileName" /> ' />
< br />
< s:property value ="caption" />
</ div >
</ body >
</ html >
ShowUpload.jsp获得imageFileName,将其UploadImages组成URL,从而将上传的图像显示出来。
然后是Action的配置文件:
<! 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 >
fileUpload Action显式地应用fileUploadStack的拦截器。
最后是web.xml配置文件:
< 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 >
发布运行应用程序,在浏览器地址栏中键入:http://localhost:8080/Struts2_Fileupload/FileUpload.jsp,出现图示页面:
清单7 FileUpload页面
选择图片文件,填写Caption并按下Submit按钮提交,出现图示页面:
清单8 上传成功页面
更多配置
在运行上述例子,如果您留心一点的话,应该会发现服务器控制台有如下输出:
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
上述信息告诉我们,struts.multipart.saveDir没有配置。struts.multipart.saveDir用于指定存放临时文件的文件夹,该配置写在struts.properties文件中。例如,如果在struts.properties文件加入如下代码:
这样上传的文件就会临时保存到你根目录下的tmp文件夹中(一般为c:/tmp),如果此文件夹不存在,Struts 2会自动创建一个。
错误处理
上述例子实现的图片上传的功能,所以应该阻止用户上传非图片类型的文件。在Struts 2中如何实现这点呢?其实这也很简单,对上述例子作如下修改即可。
首先修改FileUpload.jsp,在<body>与<s:form>之间加入“<s:fielderror />”,用于在页面上输出错误信息。
然后修改struts.xml文件,将Action fileUpload的定义改为如下所示:
< 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 >
显而易见,起作用就是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实现多文件上传也很简单。你可以将多个<s:file />绑定Action的数组或列表。如下例所示。
< 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 >
如果你希望绑定到数组,Action的代码应类似:
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; }
如果你想绑定到列表,则应类似:
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;
}
总结
在Struts 2中实现文件上传的确是轻而易举,您要做的只是使用<s:file />与Action的属性绑定。这又一次有力地证明了Struts 2的简单易用。
<script type="text/javascript"> // </script>评论:
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)
這是啥錯誤??
回复 更多评论
这是因为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);
}
} 回复 更多评论
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这个东西。应该如何解决呢? 回复 更多评论
-----------------------------------
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帮帮忙?希望自己快点长进~~~~~~~ 回复 更多评论
上传文件超过指定大小,就不能再次打开上传页面。报下面的错误:
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中如何实现的?
回复 更多评论
运行出现下面的错误提示,也就是值都没有传过去.请高手指教
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)
回复 更多评论
@Max
我现在出现如下异常,图片显示不出来
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream. < init > (FileOutputStream.java: 179 )
at java.io.FileOutputStream. < init > (FileOutputStream.java: 131 )
at tutorial.FileUploadAction.copy(FileUploadAction.java: 87 )
at tutorial.FileUploadAction.execute(FileUploadAction.java: 114 )
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 39 )
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 25 )
at java.lang.reflect.Method.invoke(Method.java: 585 )
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java: 404 )
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java: 267 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 229 )
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java: 123 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java: 167 )
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java: 86 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java: 83 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java: 121 )
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java: 86 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java: 170 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java: 176 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java: 268 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 224 )
at com.opensymphony.xwork2.DefaultActionInvocation$ 2 .doProfiling(DefaultActionInvocation.java: 223 )
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java: 455 )
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java: 221 )
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java: 50 )
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java: 504 )
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java: 419 )
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java: 1089 )
at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java: 99 )
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java: 1089 )
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java: 365 )
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java: 216 )
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java: 181 )
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java: 712 )
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java: 405 )
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java: 211 )
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java: 114 )
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java: 139 )
at org.mortbay.jetty.Server.handle(Server.java: 285 )
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java: 502 )
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java: 835 )
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java: 641 )
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java: 208 )
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java: 378 )
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java: 368 )
at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java: 442 )
2007 - 9 - 14 9 : 38 : 54 org.apache.struts2.interceptor.FileUploadInterceptor intercept
信息: Removing file myFile /tmp/upload_4b5952e6_11501ab2110__8000_00000000.tmp
大家帮我看看
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);
}
最后一次写入该写的字节就可以了。
回复 更多评论
java.io.FileNotFoundException: F:/cvs_root/struts/WebContent/UploadImages/1191902350707.bmp (系统找不到指定的路径。)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(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 回复 更多评论
method="dofileUpload">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">
application/vnd.ms-excel,text/plain
</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="input">WEB-INF/jsp/zzz/upload.jsp</result>
<result>WEB-INF/jsp/zzz/upload.jsp</result>
</action>
<action name="uploadClear" class="fileUploadAction"
method="uploadClear">
<result name="input">WEB-INF/jsp/zzz/upload.jsp</result>
<result>WEB-INF/jsp/zzz/upload.jsp</result>
</action>
uploadClear提交不到action中去,怎么会这样? 回复 更多评论
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 回复 更多评论
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 也配了 上传出现这个,。。。。 回复 更多评论
struts.xml:
<include file ="struts-default.xml" />
<action name="fileUpload" class="struts.FileUpLoad">
<interceptor-ref name ="fileUploadStack" >
<param name ="allowedTypes" >
image/bmp,image/png,image/gif,image/jpeg
</param >
</interceptor-ref >
<interceptor-ref name ="defaultStack" /> <result name ="input" >/upload.jsp</result >
<result name="success">/show.jsp</result>
upload.jsp:
<s:fielderror></s:fielderror>
<s:form action="fileUpload" method="post" enctype="multipart/form-data">
<s:file name="myFile" label="file"></s:file>
<s:textfield name="caption" label ="Caption"></s:textfield>
<s:submit></s:submit>
</s:form>
<hr>