把文件目录直接暴露给用户是很不安全的。所以要用Servlet来做,而且这样做,文件的存储方式就更丰富了,可以是从文件系统上取来的,也可以是数据库中经过计算生成的,或者从其它什么稀奇古怪的地方取来的。

public   class  DownloadServlet  extends  HttpServlet {
    
private  String contentType  =   " application/x-msdownload " ;
    
private  String enc  =   " utf-8 " ;
    
private  String fileRoot  =   "" ;


    
/**
     * 初始化contentType,enc,fileRoot
     
*/
    
public   void  init(ServletConfig config)  throws  ServletException {
        String tempStr 
=  config.getInitParameter( " contentType " );
        
if  (tempStr  !=   null   &&   ! tempStr.equals( "" )) {
            contentType 
=  tempStr;
        }
        tempStr 
=  config.getInitParameter( " enc " );
        
if  (tempStr  !=   null   &&   ! tempStr.equals( "" )) {
            enc 
=  tempStr;
        }
        tempStr 
=  config.getInitParameter( " fileRoot " );
        
if  (tempStr  !=   null   &&   ! tempStr.equals( "" )) {
            fileRoot 
=  tempStr;
        }
    }

    
protected   void  doGet(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {
        String filepath 
=  request.getParameter( " filepath " );
        String fullFilePath 
=  fileRoot  +  filepath;
        
/* 读取文件 */
        File file 
=   new  File(fullFilePath);
        
/* 如果文件存在 */
        
if  (file.exists()) {
            String filename 
=  URLEncoder.encode(file.getName(), enc);
            response.reset();
            response.setContentType(contentType);
            response.addHeader(
" Content-Disposition " " attachment; filename=\ ""  + filename +  " \ "" );
            
int  fileLength  =  ( int ) file.length();
            response.setContentLength(fileLength);
            
/* 如果文件长度大于0 */
            
if  (fileLength  !=   0 ) {
                
/* 创建输入流 */
                InputStream inStream 
=   new  FileInputStream(file);
                
byte [] buf  =   new   byte [ 4096 ];
                
/* 创建输出流 */
                ServletOutputStream servletOS 
=  response.getOutputStream();
                
int  readLength;
                
while  (((readLength  =  inStream.read(buf))  !=   - 1 )) {
                    servletOS.write(buf, 
0 , readLength);
                }
                inStream.close();
                servletOS.flush();
                servletOS.close();
            }
        }
    }

web.xml
     < servlet >
        
< servlet-name > download servlet-name>
        
<servlet-class>org.mstar.servlet.DownloadServlet servlet-class>
        
<init-param>
            
<param-name>fileRoot param-name>
            
<param-value>d:/temp param-value>
        
init-param>
        
<init-param>
            
<param-name>contentType param-name>
            
<param-value>application/x-msdownload param-value>
        
init-param>
        
<init-param>
            
<param-name>enc param-name>
            
<param-value>utf-8 param-value>
        
init-param>
    
servlet>
    
<servlet-mapping>
        
<servlet-name>download servlet-name>
        
<url-pattern>/down url-pattern>
    
servlet-mapping>