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实现文件点击下载。 将资源解压后配置在tomcat中,输入http://localhost:8080/DownLoadFileDemo/即可看到点击下载的链接
Flex+Java Servlet处理文件上传 关于上传文件
上载文件.轻松搞定.java Servlet上传文件.
包含文件 1:ajax上传删除,支持多文件实时预览; 2:jstl标签定制, ...上传使用servlet,使用跟FCK使用一样,感谢FCK,让我借鉴。支持标签定义上传类型。 当然是跨平台,支持所有浏览器 使用超级方便。
jsp+servlet实现文件下载(而不是在网页中显示出文件内容) 迅雷下载功能.zip
利用java servlet上传文件 word文档
Java servlet 和 swf上传超大文件源码Java servlet 和 swf上传超大文件源码
servlet实现上传文件和下载文件的方法,在浏览器中输入http://ip:port/servletName?path这种方式将客户端文件上传至服务器端,简单的例子,servletName参照web.xml path参照servlet中写的参数
java+jsp+servlet 文件下载
java 写的文件上传下载的例子,可以做简单图片文件服务器
基于servlet的文件下载代码基于servlet的文件下载代码基于servlet的文件下载代码基于servlet的文件下载代码基于servlet的文件下载代码基于servlet的文件下载代码基于servlet的文件下载代码基于servlet的文件下载代码...
JAVA_servlet的文件上传案例
第6章 利用Servlet上传和下载文件 6. 1 得到HTTP请求消息的内容 6. 2 利用Servlet得到上传的文件 6. 2. 1 上传文件及表单域的请求实体的分析 6. 2. 2 得到上传文件的编程实例 6. 3 使用Servlet下载文件 6. 3. ...
java servlet 文件上传 commons-fileupload-1.3.jar
本代码主要是为了解决通过servlet...另外还有通过servlet下载各种文件。同时避免中文乱码问题。如果下载后有文件无法启动的问题,请将代码移植到自己的程序中,本代码使用eclipse开发。是一个dynamic web project项目。
一个简单的Java文件上传servlet接口,文件上传成功后返回json格式响应数据,app可以调用此接口上传图片等文件到服务器,获取资源网络路径url
Flex+Java Servlet处理文件上传
两个文件上传到指定的文件里,如何处理输入输出流。借用了Apache的commons-fileupload-1.2.1.jar来完成文件上传。
1.6 与 Java Servlet 规范 2.5 版本间的兼容性 ..............................................................................................14 1.6.1 监听器(Listener)顺序 .................................
ajax异步文件上传,servlet处理