在我们提交一个表单的时候,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/天,具体规则查看活动详情