关于Struts2中实现文件上传

今天下午用Struts2.0做了一个文件上传,一老报错,想请大家帮忙看看

struts.xml如下:

<!---->



<struts>
<!---->
<constant name="struts.custom.i18n.resources" value="globalMessages"></constant>
<!---->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<package name="lee" extends="struts-default">
<!---->
<action name="Upload" class="lee.UploadAction">
<!---->
/upload
<!---->
<result>/succ.jsp</result>
</action>
</package>
</struts>





JSP页面如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<html>
<head>
<base href="&lt;%=basePath%&gt;">

&lt;title&gt;My JSP 'index.jsp' starting page&lt;/title&gt;
&lt;meta http-equiv="pragma" content="no-cache"&gt;
&lt;meta http-equiv="cache-control" content="no-cache"&gt;
&lt;meta http-equiv="expires" content="0"&gt;    
&lt;meta http-equiv="keywords" content="keyword1,keyword2,keyword3"&gt;
&lt;meta http-equiv="description" content="This is my page"&gt;
<!---->

</head>

<body>
<form enctype="multipart/form-data" method="post" action="Upload.action">
选择文件:<input name="file" type="file">

文件标题:<input name="titile" type="text">

<input type="submit" value="提交">
</form>
</body>
</html>





Action类如下:

package lee;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport
{
//封装文件标题请求参数的属性
private String title;
//封装上传文件域的属性
private File upload;
//封装上传文件类型的属性
private String uploadContentType;
//封装上传文件名的属性
private String uploadFileName;
//接受依赖注入的属性
private String savePath;

public String getTitle()
{
    return title;
}
public void setTitle(String title)
{
    this.title = title;
}
public File getUpload()
{
    return upload;
}
public void setUpload(File upload)
{
    this.upload = upload;
}
public String getUploadContentType()
{
    return uploadContentType;
}
public void setUploadContentType(String uploadContentType)
{
    this.uploadContentType = uploadContentType;
}
public String getUploadFileName()
{
    return uploadFileName;
}
public void setUploadFileName(String uploadFileName)
{
    this.uploadFileName = uploadFileName;
}
public String getSavePath()
{
    return ServletActionContext.getRequest().getRealPath(savePath);
}
public void setSavePath(String savePath)
{
    this.savePath = savePath;
}   

@Override
public String execute() throws Exception
{
    System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "<br />");
    //以服务器的文件保存地址和原文件名建立上传文件输出流
    FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
    System.out.println("bbbbbbbbbbbbbbbbbbbbbbbbbbb" + "<br />");
    //以上传文件建立一个文件上传流
    FileInputStream fis = new FileInputStream(getUpload());
    //将上传文件的内容写入服务器
    byte[] buffer = new byte[1024];
    int len = 0;
    while((len = fis.read(buffer)) &gt; 0)
    {
        fos.write(buffer, 0, len);
    }
    return SUCCESS;

}

}





响应页面如下【succ.jsp】:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<html>
<head>
<base href="&lt;%=basePath%&gt;">

&lt;title&gt;My JSP 'succd.jsp' starting page&lt;/title&gt;

&lt;meta http-equiv="pragma" content="no-cache"&gt;
&lt;meta http-equiv="cache-control" content="no-cache"&gt;
&lt;meta http-equiv="expires" content="0"&gt;    
&lt;meta http-equiv="keywords" content="keyword1,keyword2,keyword3"&gt;
&lt;meta http-equiv="description" content="This is my page"&gt;
<!---->

</head>

<body>
上传成功

<!---->
文件标题:<s:property value=" + title">
<!---->
文件为:"/>

</body>
</html>





异常如下:

2008-11-4 15:49:18 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet default threw exception
java.lang.NullPointerException
at java.io.FileInputStream.<init>(FileInputStream.java:103)
at lee.UploadAction.execute(UploadAction.java:73)
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.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:221)
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 com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:150)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:48)
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 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:186)
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 com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105)
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 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 com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:74)
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.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:127)
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.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:107)
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.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:206)
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.ChainingInterceptor.intercept(ChainingInterceptor.java:115)
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.I18nInterceptor.intercept(I18nInterceptor.java:143)
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.AliasInterceptor.intercept(AliasInterceptor.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.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.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.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:172)
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:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
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(Thread.java:595)

问题补充
好像是代码
FileOutputStream fos = new FileOutputStream(getSavePath() + "\" + getUploadFileName());
无法获取,获取的值为空,在XML文件中注入的savePath值取得到
问题补充
烦请大家帮忙看看,错误在那里。

[code="java"] //封装上传文件域的属性

private File upload; [/code]
[code="java"]
选择文件:
[/code]

这两个名字对不上,当然抛空指针了。改成一样的就可以了。

我是参考这个成功了的!
http://www.blogjava.net/max/archive/2007/03/21/105124.html
你按照上面的就可以的!

确认你的savePath目录已经建立

并请确认在Struts2的配置中上传的tempPath目录你有建立

你的log信息不完整

debug一下 应该可以找到问题的,struts2用起来还是挺简单的

路径不对

FileOutputStream fos = new FileOutputStream(getSavePath() + "\" + getUploadFileName());

而你的配置文件是 /upload

拼接起来的路径找不到吧



<!-- 配置处理文件上传的Action -->



<!-- 动态设置Action 的属性值 依赖注入方式-->

/upload

<!-- 配置struts2默认的视图页面 -->

/succ.jsp





楼顶上的。这样的配置有问题哟。
struts2 实现上传文件要配置一个上传文件的拦截器(fileUpload),当然别忘记了配置默认的拦截器哟。

interceptor-ref name="fileUpload">
image/bmp,image/png,image/gif,image/jpeg,image/jpg




<!-- 配置处理文件上传的Action -->

        <!-- 动态设置Action 的属性值 依赖注入方式-->   
        <param name="savePath">/upload</param>   
        <!-- 配置struts2默认的视图页面 -->   
        <result>/succ.jsp</result>   
    </action>   



这样试试看。不过你的路径肯定不要为null就行了。不过有个问题还是需要阐明一下。就是defaultStack本身也加入了fileUpload拦截器。这样配置就发生了两次拦截。
如果没有文件过滤的要求。那就配置一个 defaultStack 就行了。如果有文件的过滤就必须从新定义一下。当然你可以自己定义拦截起栈。这样可以让拦截的次数不是两次。如果你不愿意这样。那就只有该struts2 源码配置了

这个的name="upload"

[code="java"][/code]
[code="java"]改成[/code]
原因很简单在你写成html形式的上传文件时在struts2的action里面是找不到这个file的 一定要写成s:file的形式

选择文件:

选择文件:

[color=red] 选择文件:
[/color]

其中name的值应该和Action类中的File属性名称一样

上传的话,建议Tomcat的server.xml的connector上面的字符编码也要设置一下

兄弟,这个问题你可以下一个断点,然后在 Debug Server环境下跟踪下你的断点,看里面是否有值。
我这边有写好的例子,你邮箱多少?
我邮箱:jackzhangyunjie@163.com
回头我发给你。

FileOutputStream fos = new FileOutputStream(getSavePath() + "\" + getUploadFileName());

getSavePath() 返回的是 /upload

所以最后运行的是:
FileOutputStream fos =
new FileOutputStream("/upload\" + getUploadFileName());

知道哪里出问题勒吧?
我没运行你的程序,可能是这个问题。
碰到这种问题 直接在IDE中选择 Debug。
设断点,watch。很容易就找到原因的。
想编程,这个是必然要会的。还用记得天天用。

Over~

[code="java"]

改成
当input中的name必须与action中的属性名对应,比如现在name是upload,那对应属性名必须为uploadFileName,这样struts2自动能获得这个文件名。
在execute方法中可以这样写:
String pathtemp = request.getRealPath("/");
File dir = new File(pathtemp+"/upload/");
if(!dir.exists()){
dir.mkdir();
}
try {
FileInputStream fis = new FileInputStream(icon);
FileOutputStream fos = new FileOutputStream(dir+"/"+uploadFileName);
byte buffer[]=new byte[8192];
int count=0;
while((count=fis.read(buffer, 0, buffer.length))!=-1){
fos.write(buffer, 0, count);
}
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
[/code]

选择文件:

选择文件:

其中name的值应该和Action类中的File属性名称一样