NutzCN Logo
问答 如何在service中实现附件下载的问题
发布于 2460天前 作者 qq_7fafbecc 1423 次浏览 复制 上一个帖子 下一个帖子
标签:

页面jquery:

function downLoadFile(fileId){
	$.get(base + "/problemDemand/downLoadFile?fileId=" + fileId, function(resp){
		//$.get方法不需要再转一次json了
		//var obj = $.parseJSON(resp);
    	if(resp.code == "1"){
			//中间层正常执行
    	}else{
    		//中间层执行出现问题
    	}
	});
	//$.messager.alert('提示:','测试下载id为【'+fileId+'】的文件');
	//return;
} 

ACTION:

	@At("/downLoadFile")
    public Object downLoadFile(@Param("fileId")String fileId) {
		Object result = null;
		
		//封装参数
		NutMap re = new NutMap();
		re.setv("fileId", fileId);
		//向ComService层传入功能号和NutMap
		result = comServices.ExcuteServices("B01.01.16", re);
		return result;
		//return Json.toJson(result);
    }

service层:

	public Object downLoadFile(NutMap map) throws Exception {
		long fileId = map.getLong("fileId");
		UploadFile targetFile = dao.fetch(UploadFile.class, fileId);
		
        //获得请求文件名  
        String filename = targetFile.getUuidName();  
        System.out.println("请求下载附件:"+filename);  
          
        //设置文件MIME类型  
        response.setContentType(getServletContext().getMimeType(filename));  
        //设置Content-Disposition  
        response.setHeader("Content-Disposition", "attachment;filename="+filename);  
        //读取目标文件,通过response将目标文件写到客户端  
        //获取目标文件的绝对路径  
        String fullFileName = targetFile.getLocation() + targetFile.getUuidName() + targetFile.getExt();  
        //System.out.println(fullFileName);  
        //读取文件  
        InputStream in = new FileInputStream(fullFileName);  
        OutputStream out = response.getOutputStream();  
          
        //写文件  
        int b;  
        while((b=in.read())!= -1)  
        {  
            out.write(b);  
        }  
          
        in.close();  
        out.close(); 
        
		return null;
	}

问题:可以根据页面的get请求拿到文件、输出流也没问题,
但是怎么像servlet中一样,把流写到response中,返给浏览器呢?
浏览器的get方法的在resp.code == 1的情况下还需要做什么吗?

9 回复

ajax可不能直接触发文件下载.

而且,不用这么复杂啊 http://nutzam.com/core/mvc/view.html

@At({"/download", "/download/?"})
@Ok("raw")
public File download(@Param("fileId")long fileId) {
		UploadFile targetFile = dao.fetch(UploadFile.class, fileId);
                String fullFileName = targetFile.getLocation() + targetFile.getUuidName() + targetFile.getExt();  
                return new File(fullFileName );
}

		Mvcs.getResp().setContentType("...");
		Mvcs.getResp().setHeader("...");
		InputStream in ...
		in.read ...
		OutputStream out  ...
		out.write ...

这些in、out、contentType、head这些操作,nutz都帮我做了吗?
另外,那前台,不用$.ajax()请求,那用什么呢?

目前,我在前台对Nutz中间层的请求,有3种:
第一种:$.ajax({})

			$.ajax({
				url: base + "/problemDemand/getAttachmentByPdid",
				data: {
					"pdId": row.pdId
				},
				//表单序列化,会转变为类似a=1&b=2&c=3&d=4&e=5的值,问题是到了中间层,怎么通过@Param("..")赋值给baginfo userinfo的呢?
				dataType: "json",
				success: function(response) {
					if(response.code == '1') {
						var data = response.result;
			         	$.each(data, function (n, value) {
			            	$("#fileInfo2").append("<tr id='"+value.fileId+"'><td><a href='#' onclick='downLoadFile("+value.fileId+")' >"+value.fileName+"</a></td><td><a href='#' id='editPw'  onclick='removeFile("+value.fileId+")'>删除</a></td></tr>");
			            });
					} else {
						//alert('出错了!');
						$.messager.alert('提示:', '加载数据出错了!'+response.result);
					}
				}
			});

第二种:$.get

		$.get(base + "/problemDemand/getMaxEventExplain?pdId=" + row.pdId+"&eventType=5", function(resp){
			//$.get方法不需要再转一次json了
			//var obj = $.parseJSON(resp);
	    	if(resp.code == "1"){
	    		if(resp.result != ''){
	    			$("#handlePd_explain").textbox("setValue", '上次填写记录:【'+resp.result+'】');
	    		}else{
	    			$("#handlePd_explain").textbox("setValue", resp.result);
	    		}
	    	}
		});

第三种,提交表单:form.submit()

	//提交表单数据到后台处理
	$('#analysePdForm').form({
		url : base + "/problemDemand/analysePd",
	    onSubmit: function(){
			// do some check
			// return false to prevent submit;
	    	if( $('#analysePd_analyseType').combobox('getValue') == '') {
	    		$.messager.alert('提示:','【分析结论】不能为空!');
	    		return false;
	    	}
	    	if( $('#analysePd_analyseType').combobox('getValue') != '0' && $('#analysePd_explain').textbox('getValue') == '') {
	    		$.messager.alert('提示:','【解释说明】不能为空!');
	    		return false;
	    	}
	    },
	    success : function(data){
	    	var obj = $.parseJSON(data);
	    	if(obj.code == "1"){
	    		$.messager.alert('提示:','分析保存成功!','info',function(){
		    		closeDialogAfterSubmit();
		    		reloadPdGrid();
		    	});
	    	}else{
	    		$.messager.alert('提示:','分析保存失败!'+obj.result,'info',function(){
		    		closeDialogAfterSubmit();
		    		reloadPdGrid();
		    	});
	    	}
	    	
	    }
	});
	// submit the form
	$('#analysePdForm').submit();
}

整个项目中都是用这三种前台请求的,下载附件的请求用哪种呢?

都不行的,要开个iframe或者做个form提交才行

为什么,难道nutz的中间层的流无法回写到浏览器吗?

这跟nutz没关系,跟java都没关系,ajax就是不能直接触发下载,自行百度谷歌一下 ajax 文件下载

哦,那我先百度研究下

@wendal 昨天用用你说的iframe方法已经实现附件下载了,

function downLoadByIframe(options) {
    var config = $.extend(true, { method: 'post' }, options);
    var $iframe = $('<iframe id="down-file-iframe" />');
    var $form = $('<form target="down-file-iframe" method="' + config.method + '" />');
    $form.attr('action', config.url);
    for (var key in config.data) {
        $form.append('<input type="hidden" name="' + key + '" value="' + config.data[key] + '" />');
    }
    $iframe.append($form);
    $(document.body).append($iframe);
    $form[0].submit();
    $iframe.remove();
}

请教一下,下载时,浏览器对话框中的文件名是我的uuid名,不是文件原名,因为我怕重名,把文件是按照uuid名存放在服务器目录。
请问nutz有什么函数可以调用来重命名文件的吗?
网上大家貌似都是通过

response.setHeader("Content-Disposition", "attachment; filename="+filename);

来实现的,Nutz如何实现呢?

@Ok("raw")
public File download(@Param("fileId")long fileId) {
		UploadFile targetFile = dao.fetch(UploadFile.class, fileId);
                String fullFileName = targetFile.getLocation() + targetFile.getUuidName() + targetFile.getExt();  
                return new File(fullFileName );
}

自行设置一下Content-Disposition, nutz不会覆盖自定义的值

@Ok("raw")
public File download(@Param("fileId")long fileId, HttpServletResponse resp) {
		UploadFile targetFile = dao.fetch(UploadFile.class, fileId);
                String fullFileName = targetFile.getLocation() + targetFile.getUuidName() + targetFile.getExt(); 
                response.setHeader("Content-Disposition", "attachment; filename="+targetFile.getRealName());
                return new File(fullFileName );
}

添加回复
请先登陆
回到顶部