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("../");
}
}
分享到:
相关推荐
Java Servlet是一种Java编程语言...通过这个简单的Java Servlet实现,我们可以为用户提供一个安全、可控的文件下载服务。理解这些基本步骤和相关的HTTP概念,将有助于你更好地设计和实现Web应用程序中的文件下载功能。
Flex+Java Servlet处理文件上传 关于上传文件
总的来说,通过Java Servlet,我们可以方便地处理文件下载和在线预览的需求,无论是PDF还是其他类型的文件。在实际应用中,还需要考虑文件安全、权限控制、错误处理等复杂情况,确保服务的稳定性和安全性。
上载文件.轻松搞定.java Servlet上传文件.
综上所述,这个项目利用了`jsp`和`servlet`的技术,通过设置正确的HTTP响应头,实现了文件下载功能,同时也考虑了迅雷等下载工具的需求。在实际开发中,还需要考虑其他因素,如错误处理、日志记录和性能优化,以提供...
- **断点续传**: 虽然这个例子可能没有涵盖,但高级功能如断点续传可以提高用户体验,特别是对于大文件下载。 3. **Servlet生命周期** - **初始化**: Servlet在首次请求时被实例化,可以通过`init()`方法进行初始...
总结起来,"Java Servlet实现图片上传下载"涉及到的主要知识点有:Servlet生命周期、HTTP协议、文件I/O、数据库操作、表单提交处理、文件存储策略、安全控制、响应头设置以及异常处理。掌握这些技能,开发者可以构建...
总之,"Java(Servlet)上传文件的demo"提供了一个基础的文件上传实践案例,涵盖了从接收文件到保存文件的核心步骤,是理解Java Web中文件上传机制的一个良好起点。在实际开发中,可以根据具体需求进行扩展和优化。
包含文件 1:ajax上传删除,支持多文件实时预览; 2:jstl标签定制, ...上传使用servlet,使用跟FCK使用一样,感谢FCK,让我借鉴。支持标签定义上传类型。 当然是跨平台,支持所有浏览器 使用超级方便。
Java Servlet Programming是O'Reilly出版的一本关于Java Servlet编程的书籍,涵盖了Java Servlet的基础知识和高级主题。 本书共分为十四章,涵盖了Java Servlet的基础知识、Java Servlet的架构、Servlet生命周期、...
在给定的"java servlet jar包"中,通常包含了以下几个重要的库文件: 1. **servlet-api.jar**:这是Java Servlet API的核心库,包含了Servlet接口和Filter接口的定义,以及与之相关的类和接口。它定义了服务器如何...
通过以上步骤,你将能够创建一个基本的Java文件上传Servlet接口,它可以接收并处理来自App的文件上传请求,并以JSON格式返回响应数据。这只是一个起点,实际项目中可能需要根据需求进行更多的定制和优化。
Java Servlet API 2.5是Java Web开发中的一个重要组成部分,它是Java服务器端程序与Web应用程序交互的核心接口。这个API定义了一系列用于处理HTTP请求和响应的类和接口,为开发动态、交互式的Web应用提供了基础。在...
Java Servlet和SWFUpload是两种不同的技术,但它们在处理大文件上传方面有着共同的应用。在Web开发中,用户可能需要上传大文件,如视频、音频或大型文档,这就需要服务器端具有处理大文件上传的能力。Java Servlet是...
本教程可能包含PDF文档,如阅读器下载.htm和pdg格式的章节文件,这些文件可能提供了详细的讲解和示例代码,帮助读者深入理解Java Servlet网络编程。 总之,Java Servlet 是企业级Web开发的重要技术,通过理解和掌握...
部署Servlet应用通常涉及打包成WAR文件,然后将其放入Servlet容器的Web应用目录下。开发者可以利用IDE如Eclipse或IntelliJ IDEA中的内置工具进行调试。 总之,"JAVA Servlet 编程指南"旨在引导开发者掌握使用...
4. 文件上传下载:Servlet可以处理multipart/form-data类型的表单数据,实现文件上传下载功能。 总之,Java Servlet作为Web开发中的基石,提供了强大的服务器端功能,结合Servlet容器和其他Java EE组件,能够构建...
实现Servlet文件下载的步骤如下: 1. **创建Servlet类**:首先,你需要继承HttpServlet类并重写doGet或doPost方法,因为大多数下载请求都是GET请求,所以通常重写doGet方法。 2. **设置响应头**:在处理方法中,...
**JAVA SERVLET 高级编程** 在Java Web开发领域,Servlet是不可或缺的一部分,它为开发者提供了处理HTTP请求的能力。本教程将深入探讨Java Servlet在处理多媒体信息、集成Java Server Pages (JSP)技术、实现Servlet...
servlet实现上传文件和下载文件的方法,在浏览器中输入http://ip:port/servletName?path这种方式将客户端文件上传至服务器端,简单的例子,servletName参照web.xml path参照servlet中写的参数