用于文件下载的Servlet

本文介绍了一个用于解决Internet Explorer浏览器下载JAR文件时后缀名被错误修改的问题的Servlet实现。该Servlet能够使大部分浏览器正常下载文件,并提供了一种配置方法来避免此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在处理jar下载被IE自动将后缀修改为zip的时候,写了这么一个servlet;后面才发现原来是jboss中的mime.types中少了jar的配置,走了一大段弯路;这个Servlet在mime.types中即使没有配置的类型,大部份的浏览器都可以支持正常下载的,我的测试过程中使用七个浏览器,只有Opera在下载jar的时候会将其后缀恐怖的修改为exe。要使用这个Servlet,需要做的辅助工作就是要在web.xml中配置它,包括Servlet及servlet-mapping的配置,可参考以下内容:

<servlet> <servlet-name>downloadServer</servlet-name> <servlet-class>***.DownloadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>downloadServer</servlet-name> <url-pattern>/download_center.do</url-pattern> </servlet-mapping>

,下载文件的时候,将链接使用如下形式:

http://****.com/download_center.do?file=myfile.jar

,就可以调用该DownloadServlet进行文件的下载了,详细的可以参考一下网络上其它的资料,以下是DownloadServlet.java的完整源码:

/** * 类DownloadServlet.java的实现描述:TODO 类实现描述 文件下载Servlet * * @author root 2010-7-28 上午11:25:58 */ /** * */ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; 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 org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 8228591081694973459L; protected final static Log logger = LogFactory.getLog(DownloadServlet.class); /* * (non-Javadoc) * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { File path = new File(""); String file = request.getParameter("file");// 通过该参数传入文件名 if (!fileSafeCheck(file)) { StringBuilder sb = new StringBuilder("filename:").append(file).append(" is invalid"); if (logger.isDebugEnabled()) { logger.debug(sb.toString()); } response.setCharacterEncoding("gbk"); response.setContentLength(sb.length()); response.getWriter().write(sb.toString()); } // 以下是文件名的完整路径,具体根据情况需要自己在这里处理一下了 String filePath = path.getAbsoluteFile().getParent() + file; if (logger.isDebugEnabled()) { StringBuilder sb = new StringBuilder("filename:").append(file).append(",file absolute path:").append( filePath); logger.debug(sb.toString()); } if (filePath != null && filePath.length() > 0) { try { downloadFile(response, filePath); } catch (Exception e) { StringBuilder sb = new StringBuilder("download file exception,filename:").append(file).append( ",file absolute path:").append( filePath); logger.error(sb.toString(), e); sb.delete(0, sb.length()); // sb.append("<mce:script language=\"javascript\"><!-- alert('文件下载异常,请确定文件名是否正确.'); // --></mce:script>"); sb.append("<mce:script language=\"javascript\"><!-- alert('download file err.'); // --></mce:script>"); response.setCharacterEncoding("gbk"); response.setContentLength(sb.length()); response.getWriter().write(sb.toString()); } } } /* * (non-Javadoc) * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } /* * (non-Javadoc) * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) */ public void init(ServletConfig conf) throws ServletException { // TODO Auto-generated method stub super.init(conf); } /** * 下载文件 * * @param response * @param filePath * @throws RuntimeException * @throws IOException */ private void downloadFile(HttpServletResponse response, String filePath) throws RuntimeException, IOException { File file = new File(filePath); if (!file.exists() || !file.canRead()) { throw new RuntimeException("File not exists or can not be read!"); } FileInputStream fileinputstream = new FileInputStream(file); String filename = getFileName(filePath); downloadFile(fileinputstream, null, filename, 2048, response); fileinputstream.close(); fileinputstream = null; file = null; } /** * 下载文件 * * @param filedata 下载数据流 * @param contentType 文件类型 * @param filename (下载后的)文件名称 * @param buffersize 缓冲区大小 * @param m_response * @throws IOException * @throws BimisException */ private void downloadFile(InputStream filedata, String contentType, String filename, int buffersize, HttpServletResponse m_response) throws IOException, RuntimeException { if (filedata == null) { return; } if (buffersize <= 0) { buffersize = 2048; } long contentLengh = filedata.available(); if (contentType == null || contentType.length() == 0) { m_response.setContentType("application/x-msdownload"); } else { m_response.setContentType(contentType); } if (contentLengh > 0) { m_response.setContentLength((int) contentLengh); } String m_contentDisposition = "attachment;"; if (filename == null || filename.length() == 0) { m_response.setHeader("Content-Disposition",m_contentDisposition); } else { m_response.setHeader("Content-Disposition", m_contentDisposition + " filename=" + toUtf8String(filename)); } ServletOutputStream rspout = m_response.getOutputStream(); copyStream(filedata, rspout, buffersize, true); } /** * 将文件名中的汉字转为UTF8编码的串,以便下载时能正确显示另存的文件名. * * @param s 原文件名 * @return 重新编码后的文件名 */ private String toUtf8String(String s) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c >= 0 && c <= 255) { sb.append(c); } else { byte[] b; try { b = Character.toString(c).getBytes("utf-8"); } catch (Exception ex) { b = new byte[0]; } for (int j = 0; j < b.length; j++) { int k = b[j]; if (k < 0) k += 256; sb.append("%" + Integer.toHexString(k).toUpperCase()); } } } return sb.toString(); } private final long copyStream(InputStream source, OutputStream dest, int bufferSize, boolean flush) throws RuntimeException { int bytes; long total; byte[] buffer; buffer = new byte[bufferSize]; total = 0; try { while ((bytes = source.read(buffer)) != -1) { // Technically, some read(byte[]) methods may return 0 and we // cannot // accept that as an indication of EOF. if (bytes == 0) { bytes = source.read(); if (bytes < 0) break; dest.write(bytes); if (flush) dest.flush(); ++total; continue; } 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 fullFilePath * @return */ private String getFileName(String fullFilePath) { if (fullFilePath == null) { return ""; } int index1 = fullFilePath.lastIndexOf('/'); int index2 = fullFilePath.lastIndexOf('\\'); // index is the maximum value of index1 and index2 int index = (index1 > index2) ? index1 : index2; if (index == -1) { // not found the path separator return fullFilePath; } String fileName = fullFilePath.substring(index + 1); return fileName; } /** * 文件名的安全检查,以免被人通过"../../../"的方式获取其它文件 * * @param filename * @return */ private boolean fileSafeCheck(String filename) { if (filename.indexOf("../") >= 0) { return false; } return true; } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值