通过HttpURLConnection下载图片到本地--下载附件

一.背景说明

  现在我做的系统中,需要有一个下载附件的功能,其实就是下载图片到本地中。相应的图片保存在多媒体系统中,我们只能拿到它的资源地址(url),而不是真实的文件。

  这里记录的是下载单个图片。下篇文章中有介绍批量下载(下一篇文章)。

二.代码

1.html

/* 
 * 下载选中的附件
 */
$("#merchantApproval-annes-center-tb .downloadButton").click(function(){
    //获取选中的行,此行包含了附件的相关信息
    var row = $("#merchantApproval-annes-center-dg").datagrid("getSelected");
    if(row){
        //获取图片的资源地址
        var imgUrl = $("#imageDivId>img").attr("src");
        //向后台发送请求,参数是imgUrl和imgName
        window.location="${ctx}/approvalImageHandle.do?method=downloadImage&imgUrl="+imgUrl+"&imgName="+row.annName;
    }else{
        //如果没有选中行,则提示用户
        showTip("请选择一条记录进行操作!");
    }
});

说明:我使用的是easyui框架,数据是用datagrid中获取的。

   前台请求请使用同步请求,不要使用ajax方式,否则response输出流会直接打印到浏览器后台中,而不会成为文件让用户下载。

2.Controller

  @RequestMapping(params = "method=downloadImage")
    public void downloadImage(HttpServletRequest request, HttpServletResponse response) throws Exception{
        //图片的名称
        String imgName = request.getParameter("imgName");
        //名称转码,避免中文乱码
        imgName = new String(imgName.getBytes("iso8859-1"),"UTF-8");
        //图片的资源地址,http://10.80.3.229:8081/mediaserver/574fe515e30ab97c9068d2e1
        //这是媒体服务器返回的地址,因为是网络地址,所以需要使用HttpURLConnection去获取图片
        String imgUrl = request.getParameter("imgUrl");
        //输入流,用来读取图片
        InputStream ins = null;
        HttpURLConnection httpURL = null;
        //输出流
        OutputStream out = response.getOutputStream();
        try{
            URL url = new URL(imgUrl);
            //打开一个网络连接
            httpURL = (HttpURLConnection)url.openConnection();
            //设置网络连接超时时间
            httpURL.setConnectTimeout(3000);
            //设置应用程序要从网络连接读取数据
            httpURL.setDoInput(true);
            //设置请求方式
            httpURL.setRequestMethod("GET");
            //获取请求返回码
            int responseCode = httpURL.getResponseCode();
            if(responseCode == 200){
                //如果响应为“200”,表示成功响应,则返回一个输入流
                ins = httpURL.getInputStream();
                //设置response响应头
          //encodeChineseDownloadFileName()用来解决文件名为中文的问题,方法体在下面
response.setHeader("content-disposition", "attachment;filename="+ encodeChineseDownloadFileName(request,imgName)); //输出流到response中 byte[] data = new byte[1024]; int len = 0; while((len = ins.read(data)) > 0){ out.write(data, 0, len); } } }catch(Exception e){ LogUtil.ERROR.error("下载附件图片出错!",e); }finally{ if(ins != null){ ins.close(); } if(out != null){ out.close(); } } } /* * 解决文件为中文名的乱码问题 */ private String encodeChineseDownloadFileName(HttpServletRequest request, String pFileName) throws UnsupportedEncodingException{ String filename = null; //获取请求头中的浏览器标识 String agent = request.getHeader("USER-AGENT"); if(agent != null){ if(agent.indexOf("Firefox") != -1){ //Firefox filename = "=?UTF-8?B?" + (new String(Base64.encodeBase64(pFileName.getBytes("UTF-8")))) + "?="; }else if(agent.indexOf("Chrome") != -1){ //Chrome filename = new String(pFileName.getBytes(), "ISO8859-1"); }else{ //IE7+ filename = URLEncoder.encode(pFileName, "UTF-8"); //替换空格 filename = StringUtils.replace(filename, "+", "%20"); } }else{ filename = pFileName; } return filename; }

 

posted @ 2016-06-03 11:30  向东方  阅读(6209)  评论(0编辑  收藏  举报