`
Luob.
  • 浏览: 1592233 次
  • 来自: 上海
社区版块
存档分类
最新评论

Java Servlet下载文件(二)

    博客分类:
  • Java
 
阅读更多


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

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

import net.sf.jmimemagic.Magic;
import net.sf.jmimemagic.MagicException;
import net.sf.jmimemagic.MagicMatch;
import net.sf.jmimemagic.MagicMatchNotFoundException;
import net.sf.jmimemagic.MagicParseException;

import org.apache.log4j.Logger;

import com.sun.xml.internal.fastinfoset.stax.events.Util;

public class DownloadServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	protected static final Logger logger=Logger.getLogger(DownloadServlet.class);
	
	private String enc = "utf-8";
	private String fileRoot = "";
	private int bufferSize=2048;


	/**
	 * 初始化  enc,fileRoot
	 */
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		String tempStr=config.getInitParameter("enc");
		if(!Util.isEmptyString(tempStr)){
			enc=tempStr;
		}
		tempStr=config.getInitParameter("fileRoot");
		if(!Util.isEmptyString(tempStr)){
			fileRoot=tempStr;
		}
		tempStr=config.getInitParameter("bufferSize");
		if(!Util.isEmptyString(tempStr)){
			bufferSize=Integer.parseInt(tempStr);
		}
		
	}


	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(enc);
		response.setContentType("text/html;charset="+enc);
		//获取 请求的参数
		String filePath=request.getParameter("path");
		String fileName=request.getParameter("filename");
		
		if(!Util.isEmptyString(filePath)){
			if(Util.isEmptyString(fileRoot)){
				fileRoot=request.getSession().getServletContext().getRealPath("/");
			}
			//获取文件的 绝对路径
			String absPath=fileRoot+filePath;
			//获取 文件名
			if(Util.isEmptyString(fileName)){
				fileName=getFileName(absPath);
			}
			//安全 校验不通过
			if(!checkFileSafe(filePath)){
				StringBuilder sb=new StringBuilder("fileName:").append(fileName).append(" is invalid!");
				if(logger.isDebugEnabled()){
					logger.debug(sb.toString());
				}
				response.setContentLength(sb.length());
				response.getWriter().print(sb.toString());
				return;
			}
			if(!Util.isEmptyString(absPath)){
				try {
					if(logger.isDebugEnabled()){
						StringBuilder sb=new StringBuilder("fileName:").append(fileName).append(",file absolute path:").append(absPath);
						logger.debug(sb.toString());
					}
         //下载文件 开始	
			downloadFile(response,absPath,fileName);
				} catch (Exception e) {
					StringBuilder sb=new StringBuilder("download file exception,fileName:").append(fileName).append(",file absolute path:").append(absPath);
					logger.debug(sb.toString(), e);
					sb.delete(0, sb.length());
					sb.append("<script type=\"text/javascript\">alert(\"download file err.\");</script>");
					response.setCharacterEncoding(enc);
					response.setContentLength(sb.length());
					response.getWriter().write(sb.toString());
					return;
				} 
			}
		}else{
			StringBuilder sb=new StringBuilder("fileName:").append(fileName).append(",file directory not exists!");
			logger.debug(sb.toString());
			response.setContentLength(sb.length());
			response.getWriter().print(sb.toString());
			return;
		}
	}
	/**
	 * 下载文件
	 * 
	 * @param response
	 * @param absPath 文件的绝对路径
	 * @param fileName  文件的名字 空时 默认为  绝对路径的文件名 可以有后缀 或无后缀
	 * @throws IOException
	 */
	private void downloadFile(HttpServletResponse response,String absPath,String fileName) throws IOException{
		File file=new File(absPath);
		//判断文件是否存在 和  可读性
		if(!file.exists()|| !file.canRead()){
			throw new RuntimeException(" File not exists or can not be read.");
		}
		
		String contentType="";
		String conentDisposition="attachment;";
		
		if(!Util.isEmptyString(fileName) || !fileName.contains(".")){  
			contentType=getContentType(file,false);
			if(Util.isEmptyString(contentType)){
				contentType="application/x-msdownload";
			}
		}
		response.reset();
		FileInputStream fis=new FileInputStream(file);
		int contentLengh = fis.available();
		if(Util.isEmptyString(fileName)){
			response.setHeader("Content-Disposition",conentDisposition);
			response.setContentType(contentType);
		}else if(fileName.contains(".")){  //如果文件有后缀名 可以不用设置 contentType 浏览器会自动判断文件类型
			response.setHeader("Content-Disposition",conentDisposition+"filename="+convertFileName(fileName));
		}
		else{ //如果文件名没有后缀名 需要设置contentType
			response.setContentType(contentType);
			response.setHeader("Content-Disposition",conentDisposition+"filename="+convertFileName(fileName));
		}
		if(contentLengh>0){
			response.setContentLength(contentLengh);
		}
		
		ServletOutputStream sops=response.getOutputStream();
		copyStream(fis,sops,true);
		fis.close();
		sops.close();
		fis=null;
		sops=null;
		file=null;
	}
	/**
	 * 复制流 到 前端浏览器
	 * @param source 源文件输入流
	 * @param dest 输出流
	 * @param flush 
	 * @return
	 */
	private final long copyStream(InputStream source,OutputStream dest,boolean flush){
		int bytes;
		long total=0l;
		byte [] buffer=new byte[bufferSize];
		try {
			while((bytes=source.read(buffer))!=-1){
				if(bytes==0){
					bytes=source.read();
					if(bytes<0)
						break;
					dest.write(bytes);
					if(flush)
					   dest.flush();
					total+=bytes;
				}
				dest.write(buffer,0,bytes);
				if(flush)
					dest.flush();
				total+=bytes;
			}
			
		} catch (IOException e) {
			throw  new RuntimeException("IOException caught while copying.",e);
		}
		return total;
	}
	
	/**
	 * 根据传入的路径获取文件名
	 * @param filePath
	 * @return
	 */
	private String getFileName(String filePath){
		if(Util.isEmptyString(filePath)){
			return "";
		}
		int index1=filePath.lastIndexOf("/");
		int index2=filePath.lastIndexOf("//");
		int index=index1 > index2 ?index1:index2;
		if(index==-1)
			return filePath;
		String fileName=filePath.substring(index+1);
		return fileName;
	}
	/**
	 * 转换中文文件名 
	 * @param cfilename 中文文件名
	 * @return
	 */
    private String convertFileName(String filename){  
        try {  
        	filename=URLEncoder.encode(filename,enc);
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return filename;  
    } 
    
    /**
     * 获取文件的类型 
     * @param file
     * @return 
     * @throws MagicParseException
     * @throws MagicMatchNotFoundException
     * @throws MagicException
     */
    private String getContentType(File file,boolean extensionHints){
    	try {
    		 Magic parser = new Magic();  
    		 MagicMatch match = parser.getMagicMatch(file, extensionHints);
    		 return match.getMimeType();  
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
    }
    
    /** 
     * 文件名的安全检查,以免被人通过"../../../"的方式获取其它文件 
     * @param filePath 
     * @return false:不安全    ture:安全
     */ 
    private boolean checkFileSafe(String filePath){
    	return !filePath.contains("../");
    }
    
}

0
8
分享到:
评论

相关推荐

    java servlet实现文件下载

    Java Servlet是一种Java编程语言...通过这个简单的Java Servlet实现,我们可以为用户提供一个安全、可控的文件下载服务。理解这些基本步骤和相关的HTTP概念,将有助于你更好地设计和实现Web应用程序中的文件下载功能。

    Flex+Java Servlet处理文件上传

    Flex+Java Servlet处理文件上传 关于上传文件

    Java Servlet实现在浏览器中打开pdf文件

    总的来说,通过Java Servlet,我们可以方便地处理文件下载和在线预览的需求,无论是PDF还是其他类型的文件。在实际应用中,还需要考虑文件安全、权限控制、错误处理等复杂情况,确保服务的稳定性和安全性。

    java servlet上传文件 项目中用的.绝对能用

    上载文件.轻松搞定.java Servlet上传文件.

    java jsp+servlet实现文件下载(而不是在网页中显示出文件内容) 迅雷下载功能.zip

    综上所述,这个项目利用了`jsp`和`servlet`的技术,通过设置正确的HTTP响应头,实现了文件下载功能,同时也考虑了迅雷等下载工具的需求。在实际开发中,还需要考虑其他因素,如错误处理、日志记录和性能优化,以提供...

    servlet 文件上传下载例子

    - **断点续传**: 虽然这个例子可能没有涵盖,但高级功能如断点续传可以提高用户体验,特别是对于大文件下载。 3. **Servlet生命周期** - **初始化**: Servlet在首次请求时被实例化,可以通过`init()`方法进行初始...

    java servlet实现图片上传下载

    总结起来,"Java Servlet实现图片上传下载"涉及到的主要知识点有:Servlet生命周期、HTTP协议、文件I/O、数据库操作、表单提交处理、文件存储策略、安全控制、响应头设置以及异常处理。掌握这些技能,开发者可以构建...

    Java(Servlet)上传文件的demo

    总之,"Java(Servlet)上传文件的demo"提供了一个基础的文件上传实践案例,涵盖了从接收文件到保存文件的核心步骤,是理解Java Web中文件上传机制的一个良好起点。在实际开发中,可以根据具体需求进行扩展和优化。

    1java servlet 文件上传下载删除 当然是ajax 2jstl标签定制

    包含文件 1:ajax上传删除,支持多文件实时预览; 2:jstl标签定制, ...上传使用servlet,使用跟FCK使用一样,感谢FCK,让我借鉴。支持标签定义上传类型。 当然是跨平台,支持所有浏览器 使用超级方便。

    Java Servlet Programming

    Java Servlet Programming是O'Reilly出版的一本关于Java Servlet编程的书籍,涵盖了Java Servlet的基础知识和高级主题。 本书共分为十四章,涵盖了Java Servlet的基础知识、Java Servlet的架构、Servlet生命周期、...

    java servlet jar包

    在给定的"java servlet jar包"中,通常包含了以下几个重要的库文件: 1. **servlet-api.jar**:这是Java Servlet API的核心库,包含了Servlet接口和Filter接口的定义,以及与之相关的类和接口。它定义了服务器如何...

    Java文件上传servlet接口

    通过以上步骤,你将能够创建一个基本的Java文件上传Servlet接口,它可以接收并处理来自App的文件上传请求,并以JSON格式返回响应数据。这只是一个起点,实际项目中可能需要根据需求进行更多的定制和优化。

    Java Servlet API 2.5

    Java Servlet API 2.5是Java Web开发中的一个重要组成部分,它是Java服务器端程序与Web应用程序交互的核心接口。这个API定义了一系列用于处理HTTP请求和响应的类和接口,为开发动态、交互式的Web应用提供了基础。在...

    Java servlet 和 swf上传超大文件源码

    Java Servlet和SWFUpload是两种不同的技术,但它们在处理大文件上传方面有着共同的应用。在Web开发中,用户可能需要上传大文件,如视频、音频或大型文档,这就需要服务器端具有处理大文件上传的能力。Java Servlet是...

    深入 Java Servlet 网络编程

    本教程可能包含PDF文档,如阅读器下载.htm和pdg格式的章节文件,这些文件可能提供了详细的讲解和示例代码,帮助读者深入理解Java Servlet网络编程。 总之,Java Servlet 是企业级Web开发的重要技术,通过理解和掌握...

    JAVA servlet 编程指南

    部署Servlet应用通常涉及打包成WAR文件,然后将其放入Servlet容器的Web应用目录下。开发者可以利用IDE如Eclipse或IntelliJ IDEA中的内置工具进行调试。 总之,"JAVA Servlet 编程指南"旨在引导开发者掌握使用...

    Java Servlet

    4. 文件上传下载:Servlet可以处理multipart/form-data类型的表单数据,实现文件上传下载功能。 总之,Java Servlet作为Web开发中的基石,提供了强大的服务器端功能,结合Servlet容器和其他Java EE组件,能够构建...

    java下载类(servlet)

    实现Servlet文件下载的步骤如下: 1. **创建Servlet类**:首先,你需要继承HttpServlet类并重写doGet或doPost方法,因为大多数下载请求都是GET请求,所以通常重写doGet方法。 2. **设置响应头**:在处理方法中,...

    JAVA SERVLET 高级编程

    **JAVA SERVLET 高级编程** 在Java Web开发领域,Servlet是不可或缺的一部分,它为开发者提供了处理HTTP请求的能力。本教程将深入探讨Java Servlet在处理多媒体信息、集成Java Server Pages (JSP)技术、实现Servlet...

    java servlet实现上传/下载文件

    servlet实现上传文件和下载文件的方法,在浏览器中输入http://ip:port/servletName?path这种方式将客户端文件上传至服务器端,简单的例子,servletName参照web.xml path参照servlet中写的参数

Global site tag (gtag.js) - Google Analytics