<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
    如果Web服務器需要頻繁傳送文件給客戶端時,大多數web容器會提供異步發送的支持,像IIS中的通過ServerSupportFunction(),Apache里面apr_sendfile(),Tomcat6.X通過設置Servlet Request的請求屬性等等。。。都可以做到異步發送文件,從而提高服務器性能。

    Jetty6.X默認也不提供相關支持,本文提供一種hack方法,僅供參考:

    先看測試Servlet:
    package com.yovn.labs.testweb;

    import java.io.File;
    import java.io.IOException;

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

    import com.yovn.labs.sendfile.JettySendFile;
    import com.yovn.labs.sendfile.NormalSendFile;
    import com.yovn.labs.sendfile.SendFile;

    /**
     * 
    @author yovn
     *
     
    */
    public class SendFileServlet extends HttpServlet {

        
    protected void doGet(HttpServletRequest req, HttpServletResponse res)
                
    throws ServletException, IOException {
        
            
            
    try {
                
                File f
    =new File("D:\\workspace\\TEST.rar");//about 45M
                String action
    =req.getParameter("action");
                SendFile sf
    =null;
                
    if("1".equals(action))
                {
                    sf
    =new JettySendFile();
                }
                
    else
                {
                    sf
    =new NormalSendFile();
                }
                
    long start=System.currentTimeMillis();
                sf.doSend(req, res, f, 
    null);
                System.out.println(
    " service ok, action="+action+",use:"+(System.currentTimeMillis()-start)+"!!!");
            } 
    catch (Exception e) {
                
    throw new ServletException(e);
            }
          
        }
        
        

    }
    代碼很簡單明了,action=1時使用Jetty的異步發送,action=2時使用正常方式。

    下面是通過firefox直輸入地址回車后,下載文件,后臺的程序運行結果:
     service ok, action=1,use:62!!!
     service ok, action
    =2,use:10688!!!
     service ok, action
    =2,use:9063!!!
     service ok, action
    =1,use:47!!!
    當運行1時,實際上客戶端還沒有下完文件,但是該段代碼已經執行完了,IO的操作是異步的。
    當運行2時,客戶端下完代碼才執行完。

    以下是Jetty異步發送的代碼:
    package com.yovn.labs.sendfile;

    import java.io.File;
    import java.io.IOException;
    import java.lang.reflect.Field;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.mortbay.io.EndPoint;
    import org.mortbay.io.nio.NIOBuffer;

    /**
     * 
    @author yovn
     *
     
    */
    public class JettySendFile implements SendFile {

        
    static Field endpointField=null;
        
    static Class reqCls=null;
        
    static 
        {
            
    try {
                reqCls
    =Class.forName("org.mortbay.jetty.Request");
                endpointField
    =reqCls.getDeclaredField("_endp");
                endpointField.setAccessible(
    true);
            } 
    catch (Exception e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }
            
        
        


        
    public void doSend(HttpServletRequest req, HttpServletResponse res,File todo,String headerOpt)
                
    throws IOException {
            
            
    if(endpointField==null)throw new IOException("Jetty Not Available!!");
            
    if(!req.getClass().equals(reqCls))
            {
                
    throw new IOException("Not in Jetty Context!!");
            }
            EndPoint ep;
            
    try {
                ep 
    = (EndPoint)endpointField.get(req);
            
                
    if(headerOpt==null)
                {
                    headerOpt
    ="HTTP/1.1 200 OK \r\nContent-Type: APPLICATION/OCTET-STREAM\r\n"+
                          
    "Content-Disposition: attachment;filename=\""+todo.getName()+"\"\r\n"+
                          
    "Content-Length: "+todo.length()+"\r\n\r\n";
                }
                
    byte[] headerBytes=headerOpt.getBytes("UTF-8");
                NIOBuffer header
    =new NIOBuffer(headerBytes.length,false);
                header.put(headerBytes);
                
                NIOBuffer buffer
    =new NIOBuffer(todo);
                
                ep.flush(header, buffer, 
    null);
            } 
    catch (IllegalArgumentException e) {
                
    throw new IOException(e);
            } 
    catch (IllegalAccessException e) {
                
    throw new IOException(e);
            }
            
            
            
        }

    }

    正常發送文件的代碼:
    package com.yovn.labs.sendfile;

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

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**
     * 
    @author yovn
     *
     
    */
    public class NormalSendFile implements SendFile {

        
    /* (non-Javadoc)
         * We simply ignore the 'headerOpt'
         * @see com.yovn.labs.sendfile.SendFile#doSend(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.io.File, java.lang.String)
         
    */
        
    public void doSend(HttpServletRequest req, HttpServletResponse res,
                File todo, String headerOpt) 
    throws IOException {
            res.setHeader(
    "Content-Type""APPLICATION/OCTET-STREAM");
            res.setHeader(
    "Content-Disposition""attachment;filename=\""+todo.getName()+"\"");
            res.setHeader(
    "Content-Length", todo.length()+"");
            res.setStatus(HttpServletResponse.SC_OK);
            OutputStream out
    =res.getOutputStream();
            InputStream in
    =new FileInputStream(todo);
            
            
    byte[] buffer=new byte[8192];
            
            
    int read=0;
            
    while((read=in.read(buffer))>0)
            {
                out.write(buffer, 
    0, read);
            }
            out.flush();
            in.close();
            
            

        }

    }


    posted on 2008-03-29 01:54 DoubleH 閱讀(1770) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 四虎影视在线影院在线观看免费视频| 亚洲成a人片在线观看国产| 草久免费在线观看网站| 亚洲av乱码一区二区三区| 亚洲精品无码鲁网中文电影| 日韩毛片免费在线观看| 久久成人国产精品免费软件| 99久久99这里只有免费的精品| 亚洲s码欧洲m码吹潮| 亚洲丝袜中文字幕| 久久av无码专区亚洲av桃花岛| 久久精品亚洲福利| 亚洲av无码专区在线观看素人| 两个人的视频高清在线观看免费| 亚洲精品视频免费看| 日韩精品免费视频| 你懂的在线免费观看| 一级做a爱过程免费视| 美女被免费网站视频在线| 亚洲精品无码久久久久久| 亚洲另类视频在线观看| 亚洲系列国产精品制服丝袜第| 亚洲日本中文字幕区| 亚洲AV无码国产精品麻豆天美| 国产亚洲AV无码AV男人的天堂| 在线A亚洲老鸭窝天堂| 狠狠亚洲狠狠欧洲2019| 中文字幕精品无码亚洲字| 亚洲性猛交XXXX| 国产亚洲av片在线观看播放| 亚洲中文字幕无码日韩| 亚洲人精品午夜射精日韩| 亚洲日本va在线视频观看| 亚洲国产精华液网站w| 亚洲国产精品人久久| 亚洲黄色一级毛片| 亚洲成年人电影在线观看| 精品亚洲成在人线AV无码| 亚洲国产AV无码一区二区三区 | 青柠影视在线观看免费| 两个人看www免费视频|