注意: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;
}
}