Servlet下载

通过Servlet下载1

被下载的资源必须放到WEB-INF目录下(只要用户不能通过浏览器直接访问就OK),然后通过Servlet完成下载。

在jsp页面中给出超链接,链接到DownloadServlet,并提供要下载的文件名称。然后DownloadServlet获取文件的真实路径,然后把文件写入到response.getOutputStream()流中。

 

download.jsp

  <body>

    This is my JSP page. <br>

    <a href="<c:url value='/DownloadServlet?path=a.avi'/>">a.avi</a><br/>

    <a href="<c:url value='/DownloadServlet?path=a.jpg'/>">a.jpg</a><br/>

    <a href="<c:url value='/DownloadServlet?path=a.txt'/>">a.txt</a><br/>

  </body>

 

DownloadServlet.java

    public void doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       String filename = request.getParameter("path");[崔1] 

       String filepath = this.getServletContext().getRealPath("/WEB-INF/uploads/" + filename);[崔2] 

       File file = new File(filepath);

       if(!file.exists()) {

           response.getWriter().print("您要下载的文件不存在!");

           return;

       }[崔3] 

       IOUtils.copy(new FileInputStream(file), response.getOutputStream());[崔4] 

    }

 

上面代码有如下问题:

  1. 可以下载a.avi,但在下载框中的文件名称是DownloadServlet;
  2. 不能下载a.jpg和a.txt,而是在页面中显示它们。

 

 

3 通过Servlet下载2

下面来处理上一例中的问题,让下载框中可以显示正确的文件名称,以及可以下载a.jpg和a.txt文件。

通过添加content-disposition头来处理上面问题。当设置了content-disposition头后,浏览器就会弹出下载框。

而且还可以通过content-disposition头来指定下载文件的名称!

 

       String filename = request.getParameter("path");

       String filepath = this.getServletContext().getRealPath("/WEB-INF/uploads/" + filename);

       File file = new File(filepath);

       if(!file.exists()) {

           response.getWriter().print("您要下载的文件不存在!");

           return;

       }

       response.addHeader("content-disposition", "attachment;filename=" + filename);[崔5] 

       IOUtils.copy(new FileInputStream(file), response.getOutputStream());

 

 

  虽然上面的代码已经可以处理txt和jpg等文件的下载问题,并且也处理了在下载框中显示文件名称的问题,但是如果下载的文件名称是中文的,那么还是不行的。

 

3 通过Servlet下载3

下面是处理在下载框中显示中文的问题!

其实这一问题很简单,只需要通过URL来编码中文即可!

 

download.jsp

    <a href="<c:url value='/DownloadServlet?path=这个杀手不太冷.avi'/>">这个杀手不太冷.avi</a><br/>

    <a href="<c:url value='/DownloadServlet?path=白冰.jpg'/>">白冰.jpg</a><br/>

    <a href="<c:url value='/DownloadServlet?path=说明文档.txt'/>">说明文档.txt</a><br/>

 

DownloadServlet.java

       String filename = request.getParameter("path");

       // GET请求中,参数中包含中文需要自己动手来转换。

       // 当然如果你使用了全局编码过滤器,那么这里就不用处理了

       filename = new String(filename.getBytes("ISO-8859-1"), "UTF-8");

      

       String filepath = this.getServletContext().getRealPath("/WEB-INF/uploads/" + filename);

       File file = new File(filepath);

       if(!file.exists()) {

           response.getWriter().print("您要下载的文件不存在!");

           return;

       }

       // 所有浏览器都会使用本地编码,即中文操作系统使用GBK

       // 浏览器收到这个文件名后,会使用iso-8859-1来解码

       filename = new String(filename.getBytes("GBK"), "ISO-8859-1");

       response.addHeader("content-disposition", "attachment;filename=" + filename);

       IOUtils.copy(new FileInputStream(file), response.getOutputStream());


package servlet;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

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

import org.apache.commons.io.IOUtils;

import sun.misc.BASE64Encoder;

public class Download1Servlet extends HttpServlet {
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse resp)
			throws ServletException, IOException {
		/*
		 * 两个头一个流
		 * 1. Content-Type
		 * 2. Content-Disposition
		 * 3. 流:下载文件的数据
		 */
		
		/**
		 * 首先获取文件路径,中文编码解决,判断文件是否存在,
		 * 
		 * */
		//String filename = "F:/流光飞舞.mp3";
		
		String filename = request.getParameter("path");
		
		String filepath = this.getServletContext().getRealPath("/WEB-INF/upDloads/" + filename);
	

		// 为了使下载框中显示中文文件名称不出乱码!
//		String framename = new String("流光%飞舞.mp3".getBytes("GBK"), "ISO-8859-1");
		String framename = filenameEncoding(filename, request);
		
		String contentType = this.getServletContext()
				.getMimeType(filename);//通过文件名称获取MIME类型
		String contentDisposition = "attachment;filename=" + framename;
		// 一个流
		FileInputStream input = new FileInputStream(filepath);
		
		//设置头
		resp.setHeader("Content-Type", contentType);
		resp.setHeader("Content-Disposition", contentDisposition);
		
		// 获取绑定了响应端的流
		ServletOutputStream output = resp.getOutputStream();
		
		IOUtils.copy(input, output);//把输入流中的数据写入到输出流中。
		
		input.close();
	}
	
	// 用来对下载的文件名称进行编码的!
	public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
		String agent = request.getHeader("User-Agent"); //获取浏览器
		if (agent.contains("Firefox")) {
			BASE64Encoder base64Encoder = new BASE64Encoder();
			filename = "=?utf-8?B?"
					+ base64Encoder.encode(filename.getBytes("utf-8"))
					+ "?=";
		} else if(agent.contains("MSIE")) {
			filename = URLEncoder.encode(filename, "utf-8");
		} else {
			filename = URLEncoder.encode(filename, "utf-8");
		}
		return filename;
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值