文件上传与下载的前后端处理

这两天在搞一个东西,单据帮助内容的导入导出。具体说就是将单据的帮助信息(字段名称和帮助内容)编辑成Excel,然后上传。后端解析流,使用poi解析Excel内容并保存到数据库中。这就是导入;从数据库读取内容并装入poi里,写入输出流让前端浏览器下载,这就是导出。

就是这么简单的功能,但我却搞了两天,上传的时候request并不是类型,下载的时候已经写入response的输出流了,但浏览器就是没有弹出下载框。在网上看了个遍都不知道为什么。

后来终于知道原因了,是因为我用了Ajax向服务端发送请求。Ajax只能传递xml或json(好像有4种,网上的说法感觉都不靠谱,找时间看一看Ajax权威指南这一类的书籍,一次过彻底弄明白吧),而文件的上传下载是涉及到二进制数据的,所以Ajax做不到,只能用form请求。

上传大概是这么处理:

// 创建上传文件form
        var form = $("<form>"),   //定义一个form表单
            resFrame = $('<iframe name="res" style="display:none;"></iframe>'),
            fileInput;
        form.attr('id', uploadFormId);
        form.attr('name', uploadFormId);
        form.attr('enctype','multipart/form-data');   //在form表单中添加查询参数
        form.attr('method','post');
        form.attr('action',"");
        form.append(resFrame);
        form.attr('target','res');
        //文件浏览选择控件
        fileInput = $('<input>'); 
        fileInput.attr('id','uploadFile'); 
        fileInput.attr('type','file'); 
        fileInput.attr('name', "file[]"); 
        form.append(fileInput);

重点是设置好enctype属性和file类型的input元素。再弄一个隐藏的iframe作为form的target,好让提交form请求后页面不会刷新(伪Ajax)

public String importAction(HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws WafException,WafBizException{
        Context ctx = WafContext.getInstance().getContext();
        MultipartHttpServletRequest mReq = (MultipartHttpServletRequest)request;
        MultipartFile mf = mReq.getFile("file[]");
// ..............
}

这样子提交请求,服务端拿到的request就是MultipartHttpServletRequest,用它才可以拿到上传的文件流。

private Workbook getWb(MultipartFile mf) throws BOSException
    {
//        MultipartHttpServletRequest
        Workbook wb = null;
        try{
            String name = mf.getOriginalFilename();
            InputStream inputStream = mf.getInputStream();
            String postfix = name.substring(name.lastIndexOf(".") + 1);
            if("xls".equals(postfix)){
                POIFSFileSystem fs = null;
                fs = openWorkbookFile(inputStream);
                wb = new HSSFWorkbook(fs);
            }else if("xlsx".equals(postfix)){
                wb = new XSSFWorkbook(inputStream);
            }else{
                throw new BOSException("引入的不是以xls或xlsx为后缀的文件");
            }
        }catch(IOException e){
            throw new BOSException(e);
        }
        return wb;
    }
View Code

获取Workbook,用它来处理Excel的方式网上搜一大把

createDownloadForm = function(){
        // 创建下载文件隐藏form
        var form = $("<form>"),   //定义一个form表单
            resFrame = $('<iframe name="res" style="display:none;"></iframe>');
        form.attr('id', downloadFormId);
        form.attr('style','display:none');   //在form表单中添加查询参数
        form.attr('method','post');
        form.attr('action',"");
        form.append(resFrame);
        form.attr('target','res');
        downloadForm = form;
        return form;
    }
View Code

下载也使用form提交请求,使用Ajax无效,Ajax返回的responseText是一堆看不懂的乱码,当然浏览器不会自动下载文件。

if(isDownload)
            form.submit();
        else{
            waf.block.show({
                text: '正在导入,请稍后...'
            })
            form.ajaxSubmit({
                url: "?method="+action,
                type: "post",
                async: false,
                //dataType:"json",
                success: function(data){
                    waf.block.hide();
                    if("success" == data.result){
                        waf.msgBox.showInfo("导入成功");
                    }else{
                        waf.msgBox.showInfo(data.summany);
                    }
                },
                error: function(data){
                    waf.block.hide();
                    waf.msgBox.showInfo("导入失败");
                }
            });
        }
View Code

还有很奇怪的一点,如果是下载,一定要用调用form.submit提交,用下面的AjaxSubmit提交浏览器也不会自动下载文件。上传文件应该两种方式都可以,但AjaxSubmit可以添加返回处理函数。

// 文件名称
            String fileName = billTypeEnum.getAlias() + "-帮助内容.xlsx";
            
            // 导出,让前台浏览器自动下载
            String headerStr="attachment;filename=" + new String(fileName.getBytes("utf-8"),"ISO8859-1");
            response.setContentType(FileUploadUtils.getContentType("xlsx"));
            response.setHeader("Content-disposition",headerStr);
            ServletOutputStream output = null;
            
            output = response.getOutputStream();
            wb.write(output);
            output.flush();
            output.close();
View Code

后端大概这么处理。fileName是下载时的默认文件名。FileUploadUtils.getContentType("xlsx")返回的是"application/x-excel"。

以上代码片段,前端使用jQuery,后端使用java servlet

转载于:https://www.cnblogs.com/var-iable/p/3681702.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java是一种通用的编程语言,它可以用于开各种类型的应用程序,包括前后端上传下载文件前端后端上传下载文件的需求通常是由Web应用程序驱动的,这些应用程序需要在浏览器和服务器之间传输文件。 在Java中,可以使用多种API实现前后端文件上传下载。一种常用的API是Apache Commons FileUpload。此外,Java Servlet API也提供了一些方法来处理文件上传下载。 对于前端上传文件,可以使用HTML5的文件API来读取和上传文件。HTML5的FileReader API可以读取文件内容并将其送到服务器,而XMLHttpRequest对象可以无需刷新页面即可向服务器送请求。 后端文件上传可以通过Servlet API或Apache Commons FileUpload来实现。先通过HTTP请求接收文件,再利用Java的IO API将文件存储到磁盘上。文件下载同样也可以使用Java IO API,将文件从磁盘上读取并送到浏览器。 在实现文件上传下载时,需要注意安全性和性能问题。上传的文件必须进行验证和限制,以避免恶意用户上传无用文件或接管整个服务器。同时,文件下载需要进行缓存和保存,以提高性能和减少网络带宽的使用。 总之,Java提供了多种实现前后端文件上传下载的工具和API,可以满足不同应用程序的需求。开需要根据具体的应用场景选择合适的工具和实现方案,并关注安全和性能问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值