httpclient实现文件下载

  很久以前做文件下载都是在服务器生成文件,然后做一个链接,这样浏览器不认识的文件类型就会弹出操作系统另存对话框,实现下载,今天遇到一个案例被困了,具体需求是这样:

  在web页面点击下载按钮,服务端从数据库查询数据,组装成输出流,由response输出到客户端,由于架构中使用的第三方组件较多,所以在做这个功能时让人头疼,现将代码贴出来供兄弟们参考:

public class DownServlet extends HttpServlet {
  /**
   *
   */
  private static final long serialVersionUID = 1L;

  @Override
  protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    byte [] picbytes = "fdsafdasfds".getBytes();
    res.setContentType("application/x-download");

     // attachment:打开另存对话框;inline:用浏览器打开
    res.setHeader("Content-Disposition", "attachment;filename=fdsafd.txt");

    //res.setHeader("Content-Disposition", "inline;filename=fdsafd.txt");

    res.getOutputStream().write(picbytes);
    res.getOutputStream().flush();

  }
}

在下载应用中需要注意web.xml中是否有其他的filter和一些拦截器配置,这些可能会拦截掉下载的地址.

  下面这个类是用来抓取网络上的文件,转换成字节数组,fileUrl是文件的绝对路径,在上面的Servlet中调用download()方法,然后将setHeader()方法参数改为"inline",就可将别的网站上抓取的图片输出的自己的页面。

import  java.io.ByteArrayOutputStream;
import  java.io.InputStream;
import  org.apache.commons.httpclient.HttpClient;
import   org.apache.commons.httpclient.UsernamePasswordCredentials;
import   org.apache.commons.httpclient.auth.AuthScope;
import   org.apache.commons.httpclient.methods.GetMethod;

public class HttpDownloadService {

  public byte [] download(String fileUrl) {
    HttpClient client = new HttpClient();
    GetMethod method =  new GetMethod(fileUrl);


    client.getHttpConnectionManager().getParams().setConnectionTimeout(1000 * 60 * 5);
    client.getHttpConnectionManager().getParams().setSoTimeout(1000 * 60 * 10);
    ByteArrayOutputStream outPut = new ByteArrayOutputStream();

    try {
      UsernamePasswordCredentials upc = new UsernamePasswordCredentials("", "");
      AuthScope scope = new AuthScope(null, 0);
      client.getState().setCredentials(scope, upc);
      method.setDoAuthentication(true);


      int status = client.executeMethod(method);
      if (status != 200) {
      throw new RuntimeException("the status is " + status);
    }
           
    InputStream input = method.getResponseBodyAsStream();
    int length = 0;
    byte [] rbody = new byte[1024];
    int readNum = 0;
    while ((readNum = input.read(rbody)) > 0) {
      byte [] kk = new byte [readNum];


      for (int k = 0; k < kk.length; k++) {
        kk[k] = rbody[k];
      }


      outPut.write(kk);
      length += readNum;
      outPut.flush();
    }
           
    outPut.flush();
    outPut.close();
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    method.releaseConnection();
  }


  return outPut.toByteArray();
 }
}

以上代码尽供参考,有更好的意见或方法请赐教。

原文地址:https://www.cnblogs.com/makar/p/3250837.html