DataTables+Struts+Ajax技术的文件下载实现

1.问题分析:

通过Datatables控件所展示的数据,如果在defaultContent一列中打算通过ajax请求完成基于Strut的文件下载,则由于Strut框架特性,常常出现文件被浏览器直接打开的问题。(即使在对应的Action进行了attachment配置也不可行)


2.问题解决原理:
Datatables的ajax请求仅用于发送到查找文件的Action(Ac1),并通过Ac1返回一个真正可以下载文件url,在success回调中调用windows.open方式打开,从而将异步请求改为了同步请求。其实现原理图如下所示:
DataTables+Struts+Ajax技术的文件下载实现_第1张图片
3.代码说明
1.包含DataTable的Ajax请求Jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>




检定标准管理界面





    
    
标准设备类型 标准名称 标准适用设备 标准文件名 其他操作
2.用于查找待下载文件并返回下载url的Ac_StandardExport 
/**
 * 用于标准文件导出的Action,实际此Action只用于合成文件下载的url,具体下载执行操作由Ac_Download执行
 * @author cyoubo
 *
 */
public class Ac_StandardExport extends ActionSupport implements Preparable
{
    private static final long serialVersionUID = 107971309744984424L;
    //查询服务
    private IStandardQuery Query;
    //文件关键字
    private String devicetype;
    private String fileName;
    @Override
    public void prepare() throws Exception
    {
        //获取项目Standard主文件夹
        String standardfold=ServletActionContext.getServletContext().getRealPath("/")+"Standard/";
        //构建查询服务
        Query=new StandardQuery(standardfold);    
    }
    @Override
    public String execute() throws Exception
    {
        //准备返回文件下载的url字符串的输出流
        HttpServletResponse response = ServletActionContext.getResponse();  
        response.setContentType("text/html;charset=UTF-8");  
        PrintWriter out = response.getWriter();  
        //判断当前标准文件是否存在
        if(Query.findStandFile(DeviceType.createFromChinese(devicetype), fileName)!=null)
            //生成下载用Url(combineStandardFullPath方法在本例中用于合成待下载文件在服务器中的路径)
            out.print(Ac_Download.getActionUrl(combineStandardFullPath()));
        else 
            out.print("Error");
        return null;//由于返回的字符串,此处必须返回null以表示没有待跳转页面
    }
    /**
     * @return 合成标准文件文件的完整路径
     */
    private String combineStandardFullPath()
    {
        return "Standard/"+DeviceType.createFromChinese(devicetype).name().toUpperCase()+"/"+fileName+".xml";
    }
    //getter与setter 方法省略
}
3.用于基于Strut框架实现文件下载的Action_Dowload
/**
 * 用于实现文件的专用Action,一般由getActionUrl(String fullPath)调用文件下载操作
 * @author cyoubo
 */
public class Ac_Download extends ActionSupport
{
    private static final long serialVersionUID = 3970709669947735057L;
    /**
     * 下载文件的文件名,建议Strut.xml的action配置文件中指定fileName=${fileName},以指定下载对话框的文件名
     */
    private String fileName;
    /**
     * 现在文件在服务器中的全路径,
     */
    private String fullPath;
    /**
     * @return 获取下载文件流对象
     * @throws UnsupportedEncodingException
     */
    public InputStream getDownloadFile() throws UnsupportedEncodingException
    {
        //从传递的文件全路径中获取文件名,用于在下载对话框中展示
        String[] item=FileUtils.splitFullPath2(fullPath);
        this.fileName=item[1]+"."+item[2];
        //防止中文文件名为乱码的问题
        this.fileName = new String(this.fileName.getBytes("GBK"),"ISO-8859-1");  
        return ServletActionContext.getServletContext().getResourceAsStream(fullPath) ;  
    }
     //getter与setter 方法省略
    /**
     * 获取文件下载请求的url
     * @param fullPath 从RootWeb目录开始(不包含RootWeb)的待下载文件全路径
     * @return 可以开启文件下载Ac_Download action的url
     */
    public static String getActionUrl(String fullPath)
    {
        return "http://localhost:8081/ExDevice2/FileDownloadAction.action?fullPath="+fullPath;
    }
}
4.Strut.xml配置文件

        
	
    
  
    
         
        
            
                text/plain
                attachment;fileName="${fileName}"
                downloadFile
                1024
            
        
    





你可能感兴趣的:(DataTables+Struts+Ajax技术的文件下载实现)