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

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

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

    posts - 310, comments - 6939, trackbacks - 0, articles - 3
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    自定義開發(fā)具有Ajax功能的JSF組件

    Posted on 2007-12-23 10:01 詩特林 閱讀(2743) 評論(4)  編輯  收藏 所屬分類: JSF
     

    自定義開發(fā)具有Ajax功能的JSF組件

    使用過VB的開發(fā)人員,對組件應(yīng)該是了如指掌的了,感覺使用起來非常的方面且簡單。同樣的,JSF 擁有一個與 AWT GUI 組件模型類似的組件模型??梢杂?/span> JSF 創(chuàng)建可重用組件。但不幸的是,存在一個誤解:用 JSF 創(chuàng)建組件很困難。不要相信這些從未試過它的人們的 FUD!開發(fā) JSF 組件并不困難。由于不用一遍又一遍重復(fù)相同的代碼,可以節(jié)約時間。一旦創(chuàng)建了組件,就可以容易地把組件拖到任何 JSP、甚至任何 JSF 表單中,如果正在處理的站點有 250 個頁面,這就很重要了。JSF 的大多數(shù)功能來自基類。因為所有的繁重工作都由 API 和基類完成,所以 JSF 把組件創(chuàng)建變得很容易。

    JSF 組件由兩部分構(gòu)成:組件和渲染器。JSF組件類定義UI組件的狀態(tài)和行為;渲染器定義如何從請求讀取組件、如何顯示組件——通常通過HTML渲染。渲染器把組件的值轉(zhuǎn)換成適當?shù)臉擞?。事件排隊和性能驗證發(fā)生在組件內(nèi)部。

    這里采用自定義開發(fā)具有Ajax功能的JSF組件為例,進行JSF組件開發(fā)的講解。

    下面是我要采取的步驟:

    定義監(jiān)聽器

    l         創(chuàng)建一個類,擴展 PhaseListener

    擴展 UIComponent

    l         創(chuàng)建一個類,擴展 UIComponent

    l         保存組件狀態(tài)

    l         faces-config.xml 登記組件

    定義渲染器或者內(nèi)聯(lián)地實現(xiàn)它

    l         覆蓋 encode

    l         覆蓋 decode

    l         faces-config.xml 登記渲染器

    創(chuàng)建定制標記,繼承 UIComponentTag

    l         返回渲染器類型

    l         返回組件類型

    l         設(shè)置可能使用 JSF 表達式的屬性

    代碼下載:JSFAjax.rar

    本文中所用到的lib如下圖所示:



    一、定義監(jiān)聽器

    com.sterning.jsf.ajax. AjaxListener類:

    package com.sterning.jsf.ajax;

    import javax.faces.component.UIComponent;
    import javax.faces.component.UIViewRoot;
    import javax.faces.context.FacesContext;
    import javax.faces.event.PhaseEvent;
    import javax.faces.event.PhaseId;
    import javax.faces.event.PhaseListener;
    import javax.servlet.http.HttpServletRequest;

    import org.apache.commons.logging.*;

    public class AjaxListener implements PhaseListener {
        
    private static final transient Log log = LogFactory.getLog(com.sterning.jsf.ajax.AjaxListener.class);
        
    // 下面的常量定義了請求的參數(shù),用以決定是否為Ajax組件的請求
        private static final String AJAX_PARAM_KEY = "com.sterning.jsf.ajax.AJAX_REQUEST";
        
    private static final String AJAX_CLIENT_ID_KEY = "com.sterning.jsf.ajax.AJAX_CLIENT_ID";
            
        
    public AjaxListener() {
        }


        
    /**
         * 處理請求,從請求中獲得組件,處理后轉(zhuǎn)給response
         
    */

        
    public void afterPhase(PhaseEvent event) {
            
    if (log.isInfoEnabled()) { log.info("BEGIN afterPhase()"); }
            FacesContext context 
    = event.getFacesContext().getCurrentInstance();        
            
            HttpServletRequest request 
    = (HttpServletRequest)context.getExternalContext().getRequest();
            String ajaxParam 
    = request.getParameter(AJAX_PARAM_KEY);
            
            
    // 檢查Ajax參數(shù)
            if (ajaxParam != null && ajaxParam.equals("true")){
                
    if (log.isInfoEnabled()) { log.info("This is an ajax request."); }
                context.responseComplete(); 
                
                
    //取得Ajax組件ID
                String componentId = request.getParameter(AJAX_CLIENT_ID_KEY);  
                
    if (componentId == null){
                    
    if (log.isWarnEnabled()) { log.warn("No Client ID found under key: " + componentId); }
                }
     else {
                    handleAjaxRequest(context, componentId);
                }

                
                
    //保存頁面狀態(tài)
                context.getApplication().getStateManager().saveSerializedView(context);
            }

        }

        
        
    protected void handleAjaxRequest(FacesContext context, String ajaxClientId) {
            UIViewRoot viewRoot 
    = context.getViewRoot();
            
            AjaxInterface ajaxComponent 
    = null;
            
    try {
                ajaxComponent 
    = (AjaxInterface)viewRoot.findComponent(ajaxClientId);
            }
     catch (ClassCastException cce){
                
    throw new IllegalArgumentException("Component found under Ajax key was not of expected type.");
            }

            
    if (ajaxComponent == null){
                
    throw new NullPointerException("No component found under specified client id: " + ajaxClientId);
            }

            
            ajaxComponent.handleAjaxRequest(context);
        }


        
    public void beforePhase(PhaseEvent arg0) {
            
    // We do nothing in the before phase.
        }


        
    public PhaseId getPhaseId() {
            
    return PhaseId.RESTORE_VIEW;
        }

    }


     

    二、擴展 UIComponent

     

    1定義接口

    com.sterning.jsf.ajax.AjaxInterface接口:

    package com.sterning.jsf.ajax;

    import javax.faces.context.FacesContext;

    /**
     * 該接口應(yīng)該由Ajax組件類實現(xiàn)
     
    */


    public interface AjaxInterface {
        
        
    public void handleAjaxRequest(FacesContext context);
    }


    2.實現(xiàn)接口并繼承UIComponentBase類
    com.sterning.jsf.ajax.component. AjaxComponent
    package com.sterning.jsf.ajax.component;

    import javax.faces.component.UIComponentBase;
    import javax.faces.context.FacesContext;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    import com.sterning.jsf.ajax.AjaxInterface;
    import com.sterning.jsf.ajax.AjaxRendererInterface;


    public class AjaxComponent extends UIComponentBase implements AjaxInterface {
        
    private static final transient Log log = LogFactory
                .getLog(com.sterning.jsf.ajax.component.AjaxComponent.
    class);

        
    public static final String DEFAULT_RENDERER_TYPE = "com.sterning.jsf.ajax.component.AjaxComponentRenderer";

        
    public static final String COMPONENT_FAMILY = "com.sterning.jsf.ajax.component.AjaxComponent";

        
    public static final String COMPONENT_TYPE = "com.sterning.jsf.ajax.component.AjaxComponent";                                                                                        // Handler

        
    /**
         * 在構(gòu)函數(shù)中的setRendererType(AjaxComponent.DEFAULT_RENDERER_TYPE) 和getFamily
         * 是指定用來生成HTML代碼的渲染器,渲染器需要在faces-config.xml中進行配制
         
    */

        
    public AjaxComponent() {
            
    this.setRendererType(AjaxComponent.DEFAULT_RENDERER_TYPE);
        }


        @Override
        
    public String getFamily() {
            
    return COMPONENT_FAMILY;
        }


        
    /**
         * 當Ajax發(fā)出請求時,Ajax監(jiān)聽器將執(zhí)行此方法
         
    */

        
    public void handleAjaxRequest(FacesContext context) {
            
    // 通過Renderer進行代理
            AjaxRendererInterface renderer = (AjaxRendererInterface) this
                    .getRenderer(context);
            renderer.handleAjaxRequest(context, 
    this);
        }

    }


     

    三、定義渲染器

    下面要做的是內(nèi)聯(lián)地定義渲染器的功能。

    1.定義渲染器接口

    com.sterning.jsf.ajax. AjaxRendererInterface接口

    package com.sterning.jsf.ajax;

    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;

    public interface AjaxRendererInterface {
        
    public void handleAjaxRequest(FacesContext context, UIComponent component);
    }


    2.實現(xiàn)接口并繼承Renderer類
    com.sterning.jsf.ajax.component. AjaxComponentRenderer類
    package com.sterning.jsf.ajax.component;

    import java.io.IOException;

    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.context.ResponseWriter;
    import javax.faces.render.Renderer;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.commons.logging.*;

    import com.sterning.jsf.ajax.AjaxRendererInterface;


    public class AjaxComponentRenderer extends Renderer implements
            AjaxRendererInterface 
    {
        
    private static final transient Log log = LogFactory
                .getLog(com.sterning.jsf.ajax.component.AjaxComponentRenderer.
    class);

        
    private static final String INPUT_ID = "com.sterning.jsf.ajax.component.INPUT";

        
    private static final String INPUT_NAME = "com.sterning.jsf.ajax.component.INPUT";

        
    private static final String BUTTON_ID = "com.sterning.jsf.ajax.component.BUTTON";

        
    private static final String MESSAGE_DIV_ID = "com.sterning.jsf.ajax.component.MESSAGE_DIV";

        
    private static final String CLIENT_ID = "com.sterning.jsf.ajax.component.CLIENT_ID";

        
    /**
         * 定義渲染器。渲染器我們需要從Renderer類中繼承,不過我們一般情況下會繼承HtmlRenderer這個類,我們可以覆蓋decode
         * encodeBegin encodeChildren encodeEnd 來生成HTML
         
    */

        
    public AjaxComponentRenderer() {
        }


        
    public void encodeBegin(FacesContext context, UIComponent component)
                
    throws IOException {
            
    if (log.isTraceEnabled()) {
                log.trace(
    "begin encodeBegin()");
            }


            HttpServletRequest request 
    = (HttpServletRequest) context
                    .getExternalContext().getRequest();

            AjaxComponent ajaxComp 
    = (AjaxComponent) component;

            ResponseWriter out 
    = context.getResponseWriter();

            String clientId 
    = ajaxComp.getClientId(context);

            out.startElement(
    "div", ajaxComp);
            out.writeAttribute(
    "id", clientId, null);
            out.writeAttribute(
    "style""border:solid; width:200; height:200;",
                    
    null);

            out.startElement(
    "div", ajaxComp); // Message div
            out.writeAttribute("id", MESSAGE_DIV_ID, null);
            out.endElement(
    "div"); // Message div

            out.startElement(
    "input", ajaxComp);
            out.writeAttribute(
    "type""text"null);
            out.writeAttribute(
    "id", INPUT_ID, null);
            out.writeAttribute(
    "name", INPUT_NAME, null);
            out.endElement(
    "input");

            out.startElement(
    "button", component);
            out.writeAttribute(
    "type""button"null);
            out.writeAttribute(
    "name", BUTTON_ID, null);
            out.writeAttribute(
    "id", BUTTON_ID, null);
            out.writeAttribute(
    "value", BUTTON_ID, null);
            out.writeText(
    "Ajax It""null");
            out.endElement(
    "button");

            
    // A hidden field to hold the URL of the server for the ajax request
            out.startElement("input", ajaxComp);
            out.writeAttribute(
    "id""com.sterning.jsf.ajax.component.SERVER"null);
            out.writeAttribute(
    "type""hidden"null);
            out.writeAttribute(
    "value", request.getScheme() + "://"
                    
    + request.getServerName() + ":" + request.getServerPort()
                    
    + request.getRequestURI(), null);
            out.endElement(
    "input");

            
    // A hidden field to hold the component Client ID
            out.startElement("input", ajaxComp);
            out.writeAttribute(
    "id", CLIENT_ID, null);
            out.writeAttribute(
    "type""hidden"null);
            out.writeAttribute(
    "value", clientId, null);
            out.endElement(
    "input");

            out.write(
    "\nAjax組件\n");
            out.startElement(
    "script", ajaxComp);
            out.write(
    "dojo.addOnLoad(AjaxComponent.loadComponent());\n"); 
            out.endElement(
    "script");
        }


        
    /**
         * 處理頁面按鈕的請求, 該項按鈕通過上面的encodeBegin()方法設(shè)置
         
    */

        
    public void handleAjaxRequest(FacesContext context, UIComponent component) {
            
    if (log.isInfoEnabled()) {
                log.info(
    "BEGIN handleAjaxRequest()");
            }

            HttpServletRequest request 
    = (HttpServletRequest) context
                    .getExternalContext().getRequest();

            String textField 
    = request.getParameter(INPUT_NAME);
            String serverContribution 
    = "SERVER RESPONSE: ";
            StringBuffer xml 
    = null;

            
    if (textField == null{
                
    if (log.isInfoEnabled()) {
                    log.info(
    "No parameter found for text field.");
                }

            }
     else {
                
    if (log.isTraceEnabled()) {
                    log.trace(
    "textField: " + textField);
                }


                xml 
    = new StringBuffer("<response>");

                xml.append(
    "<message>" + serverContribution + textField
                        
    + "</message>");

                xml.append(
    "<status>OK</status></response>");
            }


            
    if (xml == null{
                
    if (log.isInfoEnabled()) {
                    log.info(
    "Response is null.");
                }

                xml 
    = new StringBuffer(this.getErrorString());
            }

            HttpServletResponse response 
    = (HttpServletResponse) context
                    .getExternalContext().getResponse();

            response.setContentType(
    "text/xml");
            response.setHeader(
    "Cache-Control""no-cache");

            
    try {
                response.getWriter().write(xml.toString());
                
    if (log.isInfoEnabled()) {
                    log.info(
    "Response sent: " + xml);
                }

            }
     catch (IOException e) {
                
    if (log.isErrorEnabled()) {
                    log.error(
    "Error writing ajax response.", e);
                }

            }


        }


        
    protected String getErrorString() {
            
    return new String(
                    
    "<response><message>There was a problem</message><status>ERROR</status></response>");
        }

    }


     

    四、創(chuàng)建定制標記

    JSF 組件不是天生綁定到 JSP 上的。要連接起 JSP 世界和 JSF 世界,需要能夠返回組件類型的定制標記(然后在 faces-context文件中登記)和渲染器。

    1.繼承UIComponentTagBase

    com.sterning.jsf.ajax.component. AjaxComponentTag

    package com.sterning.jsf.ajax.component;

    import org.apache.myfaces.shared_impl.taglib.UIComponentTagBase;

    import org.apache.commons.logging.*;

    public class AjaxComponentTag extends UIComponentTagBase {
        
    private static final transient Log log = LogFactory
                .getLog(com.sterning.jsf.ajax.component.AjaxComponentTag.
    class);

        
    /**
         * 定義標簽,在這一步中我們需要繼承UIComponentTag這個類,但在實際應(yīng)用中,
         * 我們可以繼承他的子類,比如在例子中我們就繼承HtmlOutputTextTagBase。在標簽類中,
         * 我們必須要覆蓋getComponentType方法和getRendererType,來指定這個標簽屬于哪個組件和渲染器,
         * 這兩個屬性的返回值都應(yīng)和配制文件指定的值相同。
         
    */

        
    public AjaxComponentTag() {
        }


        @Override
        
    public String getComponentType() {
            
    return AjaxComponent.COMPONENT_TYPE;
        }


        @Override
        
    public String getRendererType() {
            
    return AjaxComponent.DEFAULT_RENDERER_TYPE;
        }

    }

     

    五、登記定制標記

    現(xiàn)在要做的全部工作就是創(chuàng)建一個 TLD(標記庫描述符)文件,以登記定制標記

    WebRoot/WEB-INF/tutorial.tld

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

    <taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
        
    <tlib-version>1.3</tlib-version>
        
    <jsp-version>1.2</jsp-version>
        
    <short-name>tut</short-name>
        
    <uri>http://www.tutorial.org/jsf</uri>
        
    <description>JSF Tutorial - Ajax</description>
        
    <tag>
            
    <name>ajaxComponent</name>
            
    <tag-class>com.sterning.jsf.ajax.component.AjaxComponentTag</tag-class>
            
    <body-content>JSP</body-content>
            
    <description>
                The AjaxComponent example.
            
    </description>
            
    <!-- UIComponent attributes -->
            
    <attribute>
                
    <name>id</name>
                
    <required>false</required>
                
    <rtexprvalue>false</rtexprvalue>
                
    <type>java.lang.String</type>
                
    <description>
                    The developer-assigned ID of this component. The ID must
                    be unique within the scope of the tag's enclosing naming
                    container (e.g. h:form or f:subview). This value must be
                    a static value.
                
    </description>
            
    </attribute>
            
    <attribute>
                
    <name>binding</name>
                
    <required>false</required>
                
    <rtexprvalue>false</rtexprvalue>
                
    <type>java.lang.String</type>
                
    <description>
                    Identifies a backing bean property (of type UIComponent
                    or appropriate subclass) to bind to this component
                    instance. This value must be an EL expression.
                
    </description>
            
    </attribute>
            
    <attribute>
                
    <name>rendered</name>
                
    <required>false</required>
                
    <rtexprvalue>false</rtexprvalue>
                
    <type>java.lang.String</type>
                
    <description>
                    A boolean value that indicates whether this component
                    should be rendered. Default value: true.
                
    </description>
            
    </attribute>
        
    </tag>
    </taglib>
     

    一旦定義了 TLD 文件,就可以開始在 JSP 中使用標記了。

    WebRoot/webpages/index.jsp

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     
    <%@ page language="java" pageEncoding="GB2312"%>
    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

    <%@ taglib uri="http://www.tutorial.org/jsf" prefix="tut" %>

    <%--
    <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>
    --%>

    <link rel="stylesheet" type="text/css" href='<c:url value="/includes/styles.css"/>'>
    <script type="text/javascript" src='<%=request.getContextPath()%>/javascript/utils.js'></script>
    <script type="text/javascript" src='<%=request.getContextPath()%>/javascript/dojo.js'></script>

    <f:view>
        
    <html>
            
    <head>
            
    </head>
            
    <body>
                   
    <h:outputText value="自定義JSF Ajax組件"></h:outputText>
                   
    <form>
                       
    <tut:ajaxComponent/>
                   
    </form>
            
    </body>
        
    </html>
    </f:view>

     

    順便,WebRoot/index.html的內(nèi)容如下:

    <meta http-equiv="refresh" content="0; url=webpages/index.jsf">
     

    另外,還有兩個js文件,分別是Utils.jsdojo.js。分別位于WebRoot/javascript目錄下,請查看源代碼。

    六、配置文件

    WebRoot/WEB-INF/Web.xml文件的配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
        xsi:schemaLocation
    ="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        
    <!--
     * <b>Created:</b> Oct, 2007<br>
     * <b>Title:</b> JSF Ajax Component<br>
    -->

        
    <!-- SERVLET -->
        
    <servlet>
            
    <servlet-name>Faces Servlet</servlet-name>
            
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            
    <load-on-startup>1</load-on-startup>
        
    </servlet>
        
    <servlet-mapping>
            
    <servlet-name>Faces Servlet</servlet-name>
            
    <url-pattern>*.jsf</url-pattern>
        
    </servlet-mapping>
        
    </web-app>

     

    WebRoot/WEB-INF/faces-config.xml的代碼如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

    <faces-config>
            
    <component>
               
    <component-type>com.sterning.jsf.ajax.component.AjaxComponent</component-type>
               
    <component-class>com.sterning.jsf.ajax.component.AjaxComponent</component-class>
            
    </component>              
        
    <render-kit>    
            
    <renderer>
                
    <component-family>com.sterning.jsf.ajax.component.AjaxComponent</component-family>
                
    <renderer-type>com.sterning.jsf.ajax.component.AjaxComponentRenderer</renderer-type>
                
    <renderer-class>com.sterning.jsf.ajax.component.AjaxComponentRenderer</renderer-class>
            
    </renderer>
        
    </render-kit>
        
    <!-- LIFECYCLE -->

        
    <lifecycle>
            
    <phase-listener>com.sterning.jsf.ajax.AjaxListener</phase-listener>
        
    </lifecycle>

    </faces-config>

     

    其運行效果如下圖所示:


    評論

    # re: 自定義開發(fā)具有Ajax功能的JSF組件  回復(fù)  更多評論   

    2007-12-23 11:32 by JSF Fan
    真正的開發(fā)這么簡單的組件是遠遠不夠的,能否介紹像金蝶operamasks中datagrid那樣的復(fù)雜組件是怎么寫的?謝謝拉

    # re: 自定義開發(fā)具有Ajax功能的JSF組件  回復(fù)  更多評論   

    2007-12-23 13:16 by 千里冰封
    凡事都是從簡單做起的嘛

    # re: 自定義開發(fā)具有Ajax功能的JSF組件  回復(fù)  更多評論   

    2008-03-10 10:50 by gembin
    照上面的代碼我運行之后,為什么有如下錯誤
    SEVERE: Exception in PhaseListener RESTORE_VIEW(1) afterPhase
    java.lang.NullPointerException: No component found under specified client id: j_id_jsp_1270516925_2
    at com.sterning.jsf.ajax.AjaxListener.handleAjaxRequest(AjaxListener.java:60)
    at com.sterning.jsf.ajax.AjaxListener.afterPhase(AjaxListener.java:42)

    # re: 自定義開發(fā)具有Ajax功能的JSF組件  回復(fù)  更多評論   

    2008-03-10 10:57 by gembin
    不是原創(chuàng)吧
    主站蜘蛛池模板: 永久黄网站色视频免费直播| www亚洲精品少妇裸乳一区二区| 国产hs免费高清在线观看| 亚洲国产精彩中文乱码AV| 一本天堂ⅴ无码亚洲道久久| 中美日韩在线网免费毛片视频| 亚洲一区二区三区不卡在线播放| 亚洲最大在线观看| 免费无遮挡无遮羞在线看| **毛片免费观看久久精品| 亚洲国产精品综合久久网络 | 黄色免费网站在线看| 9420免费高清在线视频| 亚洲福利视频一区二区| 97se亚洲国产综合自在线| 中国在线观看免费的www| 精品国产免费观看| 亚洲精品中文字幕乱码影院| 亚洲午夜理论片在线观看| 久久久国产精品福利免费| 久草视频在线免费| 在线观看国产区亚洲一区成人| 亚洲色偷偷色噜噜狠狠99网| 国产精成人品日日拍夜夜免费| 黄页网站免费在线观看| 在线亚洲97se亚洲综合在线| 亚洲精品天堂无码中文字幕| 精品无码人妻一区二区免费蜜桃 | 亚洲国产精品无码久久久秋霞2| 国产成人综合亚洲| 久久久久国色AV免费看图片 | 国产成人人综合亚洲欧美丁香花 | 国产人成免费视频| 中文字幕 亚洲 有码 在线| 日本视频免费高清一本18 | 久久久久亚洲AV无码专区桃色| 亚洲欧美第一成人网站7777| 日韩不卡免费视频| 老色鬼久久亚洲AV综合| 99久久免费国产精精品| 91免费播放人人爽人人快乐|