java—servlet实现文件下载功能

最近在学javaweb技术,利用所学知识做了一个简单的项目,在服务器上实现给用户下载文件的功能。自动列出文件夹下的文件提供下载,支持中文文件名。

结果图


       其中使用了tomcat来部署服务器,代码中应用了少许EL表达式和JSTL标签,使用了jsp和servlet,当然还有java和http的基础知识,但是个人觉得重点是http的Content-Disposition头信息和Content-type头信息在servlet中下载方面的应用,详见DownloadPageServlet.java源码。

   关于Content-Disposition,可以参考一篇博客:Avatasia的博客http://www.cnblogs.com/jzaileen/articles/1281025.html

讲解的比较详细,但是代码貌似不是java的。

   关于Content-type,可以参考在线工具:

http://tool.oschina.net/commons

   本项目包含一个jsp文件,用来展示可下载的文件列表,显示为超链接,用户点击即可下载对应文件。一个javabean,用来储存可供用户下载的文件和文件名。一个servlet,用来提供下载功能。

   Jsp中超链接的实现方式:指向servlet,在网址后面附加参数,servlet可以根据附加参数知道用户想要下载哪个文件。

   结构图


备注1.本人觉得项目结构并不是很好,还望指教。

2.不知道有没有方便的专用作图软件。

如果读者对上面2个问题有所了解的话还望指导。

  

   在myeclipse中新建一个web程序,添加下述3个文件,修改一下包名错误,在web.xml中配饰上servlet,访问jsp文件,应该就可以看到效果了。

DownloadPageServlet.java源码

package com.ima.downLoad;

import java.io.BufferedInputStream;
import java.io.File;
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 com.ima.downLoad.util.FilesBean;

public class DownloadPageServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		//理论上传来的网址是 ?后面跟一个数字表示第n个文件
		String str = request.getQueryString();
		//如果没有参数则什么也不做
		if (str != null) {
			FilesBean bean = new FilesBean();
			File f = null;
			try {
				f = bean.getFiles().get(Integer.valueOf(str) - 1);
			} catch (Exception e) {
				// 没有对应文件会抛出数组越界异常
				e.printStackTrace();
				return;
			}
			System.out.println("DownloadPageServlet:用户欲得到的资源是  " + f.getName());
			if (f != null) {
				BufferedInputStream bis = null;
				try {
					// 得到文件输入流
					bis = new BufferedInputStream(new FileInputStream(f));
					// !!!
					//设置http头信息为文件下载     
					//!!!保证在下一步之前,我曾经写在下一步之后,不能正常实现功能  
					response.setContentType("application/octet-stream");
					
					response.addHeader(
							"Content-Disposition",
							"attachment;filename="
									+ URLEncoder.encode(f.getName(), "UTF-8"));
					// 得到应答输出流,并写入
					ServletOutputStream os = response.getOutputStream();
					byte[] buf = new byte[1024 * 8];
					int len = -1;
					while ((len = bis.read(buf)) != -1) {
						os.write(buf, 0, len);
					}
				} catch (Exception e) {
				} finally {
					if (bis != null)
						bis.close();
				}
			}
		}
	}

}

FileBean.java源码
package com.ima.downLoad.util;

import java.io.File;
import java.util.ArrayList;

/**
 * 获得指定文件夹下的文件,生成list,对外提供文件list和文件名list
 * @author tor
 *
 */
public class FilesBean {
	private String targetDir = "E:/imaLearn/8组共享/";
	//下面2个list应该是同步的
	//文件list,用来读取
	ArrayList<File> files = new ArrayList<File>();
	//文件名list,用来显示
	ArrayList<String> fileNames = new ArrayList<String>();

	public FilesBean() {
		init();
	}

	public ArrayList<String> getFileNames() {
		return fileNames;
	}

	/**
	 * 初始化函数,每次改变相关参数需要调用
	 */
	private void init() {
		File[] fileList = new File(targetDir).listFiles();
		for (File file : fileList) {
			if (file.canRead() && file.canWrite() && !file.isHidden()) {
				files.add(file);
				fileNames.add(file.getName());
			}
		}
	}

	

	public String getTargetDir() {
		return targetDir;
	}

	public void setTargetDir(String targetDir) {
		this.targetDir = targetDir;
		init();//重新初始化
	}

	public ArrayList<File> getFiles() {
		return files;
	}

}
showFiles.jsp源码

<%@page import="com.ima.downLoad.util.FilesBean"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib  uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>下载资源页面</title>
</head>
<body>
<h3>8组共享</h3><br/>
<%request.setAttribute("fileBean", new FilesBean()); %>
<c:forEach items="${fileBean.fileNames }" var="file" varStatus="state">
<a target="_blank" href="${pageContext.request.contextPath }/servlet/DownloadPageServlet?${state.count }">${file }</a><br/>
</c:forEach>


</body>
</html>



  • 2
    点赞
  • 0
    评论
  • 4
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

由求

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值