用Iframe来实现无刷新文件上传的注意点
1. 页面需要放一个iframe,并隐藏,然后让上传页面表单的target指定到这个iframe
2. struts2里面,中文文件编码处理,可以在配置文件,也可以在action取上传文件名字的地方,看下面代码。
3. 上传完成后,还是提交返回到上传页面,但是后台上传成功的提示信息回传时,在js 里面,都必须用parent.xxx的方式,才能访问到iframe外面的变量和js方法,有点嵌套的意思,比较搞。
4. 上传页面可以再放一个form,用来下载用。
5. struts2一般出错或者取不到值,都是对valueStack和ognl 理解不准确导致的,#号访问valuestack中非root节点的值,不用#访问的是action里面属性的值,因为action默认是这个valuestack的root节点。
6. struts2 action要取得属性值,前台form必须提交过去,就算没用到,就用隐藏域传,否则后台取回报空指针。多文件上传下载例子里有实例。
7. 无刷新上传,还是不要用iframe,太麻烦。尤其是js访问iframe外面的方法和变量,或者提交表单,全部要加parent
上代码
上传action,BaseAction其实没啥,只是提炼了些公用方法,也是直接继承ActionSupport
package com.hello.web.upAndDownload;
import java.io.File;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hello.util.CommonConstants;
import com.hello.util.FileUtil;
import com.hello.web.BaseAction;
import com.opensymphony.xwork2.ActionContext;
/**
* 单文件上传Action
* */
public class FileUploadAction extends BaseAction {
private static final long serialVersionUID = 3458871754829140760L;
private Logger logger = LoggerFactory.getLogger(FileUploadAction.class);
private File upload;//页面上传文件栏位名
private String uploadContentType;//文件类型 struts2框架使用,用于判断是否包含不支持的上传类型
private String uploadFileName;//文件名称
private String saveFileName;//文件转存后的名字
/**跳转到上传界面*/
public String goUploadPage(){
logger.debug("跳转到上传界面");
return "uploadPage";
}
/**
* 执行文件上传
* */
public String uploadFile(){
logger.debug("上传文件名称:"+uploadFileName);
logger.debug("上传文件类型:"+uploadContentType);
try
{
String fileName = FileUtil.generDateStrFilename(uploadFileName);
HttpServletRequest request = ServletActionContext.getRequest();
String contextPath = request.getContextPath();//获取应用上下文路径
String destPath = ServletActionContext.getServletContext().getRealPath("/"+CommonConstants.uploadFilePath);
//logger.debug("保存路径:"+destPath);
File destFile = new File(destPath+File.separator+fileName);
//拷贝文件
FileUtil.copyFile(upload, destFile);
//将文件路径返回到页面,以供显示
// 方式访问
request.setAttribute("realFilePathName", contextPath+"/"+CommonConstants.uploadFilePath+"/"+fileName);
//文件重名后的名字
this.setSaveFileName(fileName);
}catch(Exception e){
logger.error(uploadFileName+"文件上传出错:",e);
}
return SUCCESS;
}
/**
* 无刷新
* */
public String iframeUpload(){
logger.debug("上传文件名称:"+uploadFileName);
logger.debug("上传文件类型:"+uploadContentType);
try
{
String fileName = FileUtil.generDateStrFilename(uploadFileName);
HttpServletRequest request = ServletActionContext.getRequest();
String contextPath = request.getContextPath();//获取应用上下文路径
String destPath = ServletActionContext.getServletContext().getRealPath("/"+CommonConstants.uploadFilePath);
//logger.debug("保存路径:"+destPath);
File destFile = new File(destPath+File.separator+fileName);
//拷贝文件
FileUtil.copyFile(upload, destFile);
//将文件路径返回到页面,以供显示
request.setAttribute("realFilePathName", contextPath+"/"+CommonConstants.uploadFilePath+"/"+fileName);
//文件重名后的名字
this.setSaveFileName(fileName);
ActionContext.getContext().put("message", "上传成功!");
}catch(Exception e){
logger.error(uploadFileName+"文件上传出错:",e);
}
return SUCCESS;
}
/**跳转到上传界面*/
public String goIframeUploadPage(){
logger.debug("跳转到上传界面");
return "iframeUpload";
}
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 getSaveFileName() {
return saveFileName;
}
public void setSaveFileName(String saveFileName) {
this.saveFileName = saveFileName;
}
}
下载Action
package com.hello.web.upAndDownload;
import java.io.InputStream;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hello.util.CommonConstants;
import com.hello.web.BaseAction;
/**
* 文件下载
* 必须用表单提交,且方法为POST,才能将隐藏域的值传进来
* jsp里面有fileName,则action里面使用setFileName方法对应,其他变量类似
* jsp里面取${downloadFileName},相当于调用action里面的getDownloadFileName方法
*
* */
public class FileDownLoadAction extends BaseAction {
private static final long serialVersionUID = -929993646660508444L;
private Logger logger = LoggerFactory.getLogger(FileDownLoadAction.class);
//下载显示的文件名
private String downloadFileName;
private String realFileName;
/**
* 执行下载
* */
public String download(){
logger.debug("下载的文件显示名:"+downloadFileName);
logger.debug("下载的文件实际名:"+realFileName);
HttpServletRequest request = ServletActionContext.getRequest();
logger.debug("从隐藏域里面取得的值:"+request.getParameter("realFileName"));
return SUCCESS;
}
public InputStream getInputStream() {
logger.debug("下载的文件显示名:"+downloadFileName);
logger.debug("下载的文件实际名:"+realFileName);
//InputStream in = ServletActionContext.getServletContext().getResourceAsStream("/" +CommonConstants.uploadFilePath+"/"+ downloadFileName);
InputStream in = ServletActionContext.getServletContext().getResourceAsStream("/" +CommonConstants.uploadFilePath+"/"+ realFileName);
if(in==null){
logger.debug("检查action中文件下载路径是否正确!");
}
return in;
}
public void setFileName(String fileName) {
this.downloadFileName = fileName;
}
public String getDownloadFileName() {
String finalFileName = downloadFileName;
try {
// 解决文件名称包含中文
HttpServletRequest request = ServletActionContext.getRequest();
String userAgent = request.getHeader("USER-AGENT");
if (StringUtils.contains(userAgent, "MSIE")) {// IE浏览器
finalFileName = URLEncoder.encode(downloadFileName, "UTF8");
} else if (StringUtils.contains(userAgent, "Mozilla")) {// google,火狐浏览器
finalFileName = new String(downloadFileName.getBytes(), "ISO8859-1");
} else {
finalFileName = URLEncoder.encode(downloadFileName, "UTF8");// 其他浏览器
}
} catch (Exception e) {
logger.error("下载时,文件名称转码出错:", e);
}
return finalFileName;
}
public String getRealFileName() {
logger.debug("调用 getRealFileName 方法:"+realFileName);
return realFileName;
}
public void setRealFileName(String realFileName) {
logger.debug("调用 setRealFileName 方法:"+realFileName);
this.realFileName = realFileName;
}
}
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
使用Iframe实现无刷新文件上传
请选择文件:
(只支持上传JPG,PNG,GIF,TXT文件)
---------------------------------------------------------------------
0}">
"/>
">返回首页
配置文件
struts.xml主文件
message
/WEB-INF/pages/error/404.jsp
/WEB-INF/pages/error/500.jsp
/index.jsp
/WEB-INF/pages/msg/message.jsp
/index.jsp
/WEB-INF/pages/error/404.jsp
struts-upload2download-test.xml
1048576
image/bmp,image/png,image/gif,image/jpeg,image/jpg,text/plain
/WEB-INF/pages/upload2down/upload.jsp
/WEB-INF/pages/upload2down/uploadSuccess.jsp
/WEB-INF/pages/upload2down/upload.jsp
application/octet-stream
inputStream
attachment;filename="${downloadFileName}"
4096
1048576
image/bmp,image/png,image/gif,image/jpeg,image/jpg,text/plain
/WEB-INF/pages/upload2down/multiUpload.jsp
/WEB-INF/pages/upload2down/multiUploadSuccess.jsp
/WEB-INF/pages/upload2down/multiUpload.jsp
1048576
image/bmp,image/png,image/gif,image/jpeg,image/jpg,text/plain
/WEB-INF/pages/upload2down/ajax1Upload.jsp
/WEB-INF/pages/upload2down/ajax1Upload.jsp
/WEB-INF/pages/upload2down/ajax1Upload.jsp