在我们提交一个表单的时候,struts2会跳转到另一个页面进行处理
如action中如下配置
<result type="redirect">admin/index.jsp?ceshi=ceshi1</result>
此表示,当处理结果成功后会跳转到页面admin/index.jsp?ceshi=ceshi1
如果我们写配置,写成这样
<result type="redirect"></result>即没有返回的视图页面,就会报错
2015-11-25 10:20:34,265 [ERROR] [org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler] - Exception occurred during processing request: null
java.lang.NullPointerException
at org.apache.struts2.dispatcher.ServletRedirectResult.isPathUrl(ServletRedirectResult.java:276)
at org.apache.struts2.dispatcher.ServletRedirectResult.doExecute(ServletRedirectResult.java:180)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:191)
at org.apache.struts2.dispatcher.ServletRedirectResult.execute(ServletRedirectResult.java:164)
因此,我们就有必要使用ajax来提交表单,但是有一个问题,如果表单中的类型是基本类型,如,文本,数字,时间等,用ajax是没有问题的
但是如果是文件类型,如我们上传文件,使用ajax按照传统的方法就会报错的,报错为参数不对
此时我们就需要使用FormData来完成
请看如下表单
<s:form action="ACupfile" method="post" enctype="multipart/form-data" id="formFile">
<s:file id="file" name="file" onchange="saveFile();"/>
<s:textfield id="filename" name="filename" />
</s:form>
上面的表单定义了一个表单,这个表单相信大家一定看得懂,需要注意的是enctype的值必须应该是"multipart/form/-data"
然后我们看看saveFile()函数是怎么写的
function saveFile(){
$("#filename").val($("#file").val());
var formData = new FormData($("#formFile")[0]);
$.ajax({
url:"ACupfile.action",
type:"POST",
data:formData,
async:false,
cache:false,
dataType:"text",
contentType:false,
processData:false,
success:function(){
alert(123);
},
error:function(){
alert(789);
}
});
}
上面函数的关键点在于
1,var formData = new FormData($("#formFile")[0]) 得到一个formData 对象,参数为表单
2,contentType 为 false,因为FormData 已经封装进去了
3,processData 为 false,告诉ajax不用去处理数据(FormData),因为数据已经被封装
现在我们来看看struts.xml怎么配置的
<!-- 上传过程中临时保存的位置 --> <constant name="struts.multipart.saveDir" value="d:\strutstemp\" />以上设置的是上传文件临时的保存位置
<action name="ACupfile" class="upfile"> <result type="redirect">admin/index.jsp?ceshi=ceshi1</result> <result name="input" type="redirect">admin/index.jsp?ceshi=ceshi</result> <interceptor-ref name="fileUpload"> <param name="allowedType"> image/bmp,image/png,image/gif,image/jpeg,image/jpg </param> <param name="maximumSize">1048576</param> </interceptor-ref> <interceptor-ref name="defaultStack" /> </action>因为是使用的ssh框架,所以上面的action的值是由spring提供的,上面的配置在于配置拦截器,拦截器fileUpload是自带的拦截器,我们需要配置上传文件的类型以及大小
然后需要添加默认的拦截器 defaultStack
然后我们看看action中如何实现接收数据,以下代码为我项目中直接拷贝,大家可以参考下。
public class UploadFile extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private List<File> file;
private String filename;
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String execute(){
//获得项目的根地址,/LoveB
String root = ServletActionContext.getRequest().getContextPath();
//获得项目的实际路劲
String path = (Thread.currentThread().getContextClassLoader().getResource("").toString()).replace('/', '\\').replace("file:", "").replace("classes\\", "").replace("WEB-INF\\", "").substring(1).replace("%20", " ");
//仅仅得到名字
String fileName = filename.split("\\\\")[filename.split("\\\\").length-1];
//仅仅得到一个服务器保存的名字:日期_fileName
String newfilename = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+"_"+fileName;
//获得新的文件名全路劲
String newpath = path+"Face\\upload\\"+newfilename;
//开始写入文件,图片采用二进制
FileInputStream fis = null ;
FileOutputStream fos = null ;
DataOutputStream dos = null;
DataInputStream dis = null;
//获得文件,获得服务器临时的文件
File file_client = new File(file.get(0).getPath());
//服务器上的文件,没有就创建
File file_service = new File(newpath);
try {
//创建磁盘输出对象,输出到磁盘
fos = new FileOutputStream(file_service);
dos = new DataOutputStream(fos);
//创建磁盘输入对象 即是获得这个输入对象
fis = new FileInputStream(file_client);
dis = new DataInputStream(fis);
int temp = dis.read();
while(temp != -1){
dos.write(temp);
temp = dis.read();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return SUCCESS;
}
}
以上就完成了ssh框架中struts2上传文件的实现
关于FormData 可以参考这里
https://developer.mozilla.org/zh-CN/docs/Web/Guide/Using_FormData_Objects
爆款云服务器s6 2核4G 低至0.46/天,具体规则查看活动详情