典型 使用servlet下载文件(缓存处理)

注意:servlet是单例,多用线程共享,它的成员变量就是相当于静态变量;

servlet的init方法只在servlet第一被访问加载servlet时,只实例化一次,因此可作为缓存处理。

例子

1.jsp页面请求下载(携带文件名参数)

<%
 String fileDisplay = "";
 String floderName="";
 String fileterPath="/mylient/";
 if (request.getParameter("floderName") != null)
 {
  floderName = request.getParameter("floderName").toString();
 }
 if (request.getParameter("domain") != null)
 {
  fileDisplay = request.getParameter("domain").toString();
 }
 String realPath = request.getContextPath();
 
 if("mediaxDownload".equals(floderName))
 {
  fileterPath="/downloadMyClient/";
 }

    fileDisplay = realPath + fileterPath
   + fileDisplay;
   
 //System.out.println(fileDisplay);  
 response.sendRedirect(fileDisplay);   //跳转一个路径,被servlet拦截,获取文件名,返回文件刘下载
%>

2. 下载文件的servlet1(下载目标文件不同)

package com.test.download;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;

public class DownloadServlet extends BaseDownloadServlet
{
 private static final long serialVersionUID = 4893691975014133693L;   

 @Override
 public void init() throws ServletException           //servlet的init方法,只在servle第一次访问加类载时,只初始化一次,做初始化操作,也可以在web.xml配置上下文监听
 {
  super.init();

  StringBuffer strBuf = new StringBuffer(256);
  strBuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    .format(new Date()));
  strBuf.append(" [DownloadServlet.init()]");
  strBuf.append("  Web App real path: ");
  strBuf.append(getServletContext().getRealPath("/"));
  System.out.println(strBuf.toString());

  String exeFile = getServletContext().getRealPath("/")
    + "download/test.zip";
  DownloadManager downloadManager = new DownloadManager();
  try
  {
   fileBytes = downloadManager.readDownloadBytes(exeFile);
  }
  catch (Exception e)
  {
   fileBytes = null;
   e.printStackTrace();
  }
 }
}

3.下载文件的servlet2(下载目标文件不同)

package com.test.download;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;

public class DownloadMyServlet extends BaseDownloadServlet
{
 private static final long serialVersionUID = -3852849686144408062L;

 @Override
 public void init() throws ServletException
 {
  super.init();

  StringBuffer strBuf = new StringBuffer(256);
  strBuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    .format(new Date()));
  strBuf.append(" [DownloadMXServlet.init()]");
  strBuf.append("  Web App real path: ");
  strBuf.append(getServletContext().getRealPath("/"));
  System.out.println(strBuf.toString());

  String exeFile = getServletContext().getRealPath("/")
    + "mediaxDownload/mcmeeting.exe";
  DownloadManager downloadManager = new DownloadManager();
  try
  {
   fileBytes = downloadManager.readDownloadBytes(exeFile);
  }
  catch (Exception e)
  {
   fileBytes = null;
   e.printStackTrace();
  }
 }
}

4. servlet的父类(重用方法)

package com.test.download;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BaseDownloadServlet extends HttpServlet

 private static final long serialVersionUID = 6731138163201257067L;

 protected byte[] fileBytes = null;   //这里是servlet的成员变量,缓存目标文件流,它属于类级别,相当于静态属性(各servlet类之间互不干扰)
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException
 {
  doPost(req, resp);
 }

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException
 {
  String url = req.getRequestURI();
  String resFileName = url.substring(url.lastIndexOf("/") + 1, url
    .length());
  PrintWriter out = resp.getWriter();
  if (null != fileBytes)
  {
   OutputStream opts = null;
   try
   {
    resp.reset();
    resp.setContentType("application/x-msdownload");
    resp.setHeader("Content-Disposition", "attachment;filename="
      + resFileName);
    opts = resp.getOutputStream();
    opts.write(fileBytes);

    StringBuffer strBuf = new StringBuffer(512);
    strBuf.append(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
     .append(" [BaseDownloadServlet.doPost()]")
     .append("  This Is Local Download Server! User IP: ").append(req.getRemoteAddr())
     .append(" fileName: ").append(resFileName);
    System.out.println(strBuf.toString());
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {
    if (null != opts)
    {
     opts.close();
     opts = null;
    }

    if (null != out)
    {
     out.close();
     out = null;
    }
   }
  }
  else
  {
   out.println("<center>download file is not exsit!</center>");
   
   StringBuffer strBuf = new StringBuffer(512);
   strBuf.append(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
    .append(" [BaseDownloadServlet.doPost()]")
    .append("  This Is Local Download Server! User IP: ").append(req.getRemoteAddr())
    .append(" fileBytes is null, fail to download file: ").append(resFileName);
   System.out.println(strBuf.toString());
  }
 }
}

5.下载服务类

package com.test.download;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 下载文件
 *  *
 */
public class DownloadManager
{
 /**
    * @param exeFile
    * @throws Exception
  *             读写文件异常
  */
 public byte[] readDownloadBytes(String exeFile)
   throws Exception
 {

  File exe = new File(exeFile);
  BufferedInputStream bis = null;
  FileInputStream fis = null;
  ByteArrayOutputStream bos = null;
  byte[] fileBytes = null;
  
  try
  {
   fis = new FileInputStream(exe);
   bis = new BufferedInputStream(fis);   //这里要传声明的对象,不要使用匿名类,放置异常时流不能关闭,如将bis = new BufferedInputStream(fis);   改为  new BufferedInputStream(new FileInputStream(exe));   

    int dataSize = 1024 * 200;
   byte[] bt = new byte[dataSize];
   bos = new ByteArrayOutputStream();
   int readLen = 0;
   while ((readLen = bis.read(bt)) > 0)
   {
    bos.write(bt, 0, readLen);   //这里读取的是实际长度,不能为bos.write(bt, 0, bt.length);否则最后一次读取时,会在文件流末尾多加了空字节   
   }
   
   fileBytes = bos.toByteArray();
  }
  finally
  {
   if (null != bis)
   {
    try
    {
     bis.close();    //所有的流都要关闭,如果关闭异常,在需要try catch(不做操作),保证流程继续向下走
    }
    catch (Exception e)
    {
     // do nothing.
    }
    
    bis = null;
   }
   
   if (null != fis)
   {
    try
    {
     fis.close();
    }
    catch (Exception e)
    {
     // do nothing.
    }

    fis = null;
   }
   
   if (null != bos)
   {
    try
    {
     bos.close();
    }
    catch (Exception e)
    {
     // do nothing.
    }
    
    bos = null;
   }
  }

  StringBuffer strBuf = new StringBuffer(256);
  strBuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  strBuf.append(" [DownloadManager.readDownloadBytes()]");
  strBuf.append("  Reading download file, file size in byte: ");
  strBuf.append(fileBytes.length);
  System.out.println(strBuf.toString());
  
  return fileBytes;
 }
}

原文地址:https://www.cnblogs.com/qqzy168/p/2771340.html