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

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

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

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

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

    Jetty6.X默認(rèn)也不提供相關(guān)支持,本文提供一種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的異步發(fā)送,action=2時使用正常方式。

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

    以下是Jetty異步發(fā)送的代碼:
    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);
            }
            
            
            
        }

    }

    正常發(fā)送文件的代碼:
    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)  編輯  收藏

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 皇色在线免费视频| 猫咪免费人成在线网站| 国产区图片区小说区亚洲区| 亚洲片一区二区三区| 一区二区三区四区免费视频 | 午夜老司机免费视频| 特级毛片全部免费播放| 日本亚洲成高清一区二区三区| 96免费精品视频在线观看| 亚洲国产高清国产拍精品| 情人伊人久久综合亚洲| 最近最好的中文字幕2019免费 | 亚洲av片在线观看| 亚洲成a人片77777kkkk| 日韩免费视频网站| 久久大香伊焦在人线免费| 国产亚洲精品AAAA片APP| 亚洲三级电影网址| 国产免费牲交视频| 91免费在线播放| kk4kk免费视频毛片| 99久久婷婷国产综合亚洲| 亚洲日韩激情无码一区| 在线播放高清国语自产拍免费 | 亚洲性在线看高清h片| h视频免费高清在线观看| 亚洲中文无码亚洲人成影院| 久久亚洲AV无码精品色午夜麻| 波多野结衣视频在线免费观看| 免费黄色福利视频| 国产永久免费高清在线| 色欲aⅴ亚洲情无码AV蜜桃| 亚洲伊人久久大香线蕉啊| 亚洲av无码一区二区三区网站| 免费人妻av无码专区| 成年女人视频网站免费m| 最近中文字幕无免费| a级毛片在线免费观看| 污视频网站在线免费看| 亚洲国产精品无码观看久久| 亚洲人成人77777网站不卡|