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

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

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

    176142998

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      116 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

    #

    分析:EOFException表示輸入過程中意外地到達文件尾或流尾的信號,導致從session中獲取數據失敗。異常是tomcat本身的問題,由于tomcat上次非正常關閉時有一些活動session被持久化(表現為一些臨時文件),在重啟時,tomcat嘗試去恢復這些session的持久化數據但又讀取失敗造成的。此異常不影響系統的使用。
    解決辦法:將tomcat5.5\work\Catalina\localhost\peam\SESSIONS.ser刪除。如果正常關閉服務端,該文件是自動刪除的。
    posted @ 2008-07-09 22:59 飛飛 閱讀(207) | 評論 (0)編輯 收藏

    當增加Hibernate Capabilites后增加Struts Capabilites,運行項目時,控制臺報錯信息:
    /----------------------------------------------org.apache.commons.collections.SequencedHashMap
    ......
    /----------------------------------------------
    解決方案:
    下載commons-beanutils-1.7.0.zip;
    將其中commons-beanutils.jar文件替換Tomcat6.0下WEB-INF/lib/commons-beanutils-1.7;
    解決問題.

    這個錯誤可能是myeclipse6.0版本的一個問題,就是在整合web層和struts層出現的問題

    解決方法如下:

    1)下載6.0.1版本的myeclipse開發

    2)下載最新的org.apache.commons.collections,講原來的去掉就行了,然后講最新的加進去

    posted @ 2008-07-09 20:53 飛飛 閱讀(781) | 評論 (0)編輯 收藏

    <html:messages>
    Action 中 :
            ActionMessages message = new ActionMessages();
            message.add(" 消息句柄 ",new ActionMessage(" 資源文件中 Key 值 ",String 類型描述信息 ));
            this.addMessages(request,message);
            return ActionForward;
    JSP 頁面中 :
            <html:messages id=" 指定使用消息的標識 " property=" 消息句柄 " message="true|false">
               <bean:write name=" 以上所指 ID 標識 "/>
            </html:messages>

    例如:

    Action方法中:
    saveMessage(request,"頁面要顯示的消息");

    Action的調用的方法,可以寫真Action實現類的父類 BaseDispatchAction :

    public ActionMessages saveMessage(HttpServletRequest request, String key) {
          ActionMessages messages = new ActionMessages();
          return saveMessage(messages, request, key);
    }

    protected ActionMessages saveMessage(ActionMessages messages,
           HttpServletRequest request, String key) {

          messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(key));
          saveMessages(request, messages);
          return messages;
    }

    頁面:

    <html:messages id="msg" message="true"><bean:write name="msg"/></html:messages>

     

    <html:errors>
    Action 中 :
            ActionMessages message = new ActionMessages();
            message.add(" 消息句柄 ",new ActionMessage(" 資源文件中 Key 值 ",String 類型描述信息 ));
            this.saveErrors(request,message);
            return ActionForward;
    JSP 頁面中 :
            <html:errors property=" 消息句柄 "/>

    如果Action中這樣設定(false),頁面的提示信息將不從資源文件里讀取:
            ActionMessages message = new ActionMessages();
            message.add("消息句柄",new ActionMessage("String類型描述信息));",false));
            this.saveErrors(request,message);
            return ActionForward;
    JSP頁面:
            <html:errors/>或<html:errors property="消息句柄"/>

    posted @ 2008-07-09 17:21 飛飛 閱讀(336) | 評論 (0)編輯 收藏

    源碼下載:http://ishare.iask.sina.com.cn/cgi-bin/fileid.cgi?fileid=2857703

    1. 準備

    工具:MyEclipse 6.0.1 GAmysql-connector-java-5.0.4-bin.jarMySql GUI Tools 5.0(便于管理MySql數據庫,不是必須)

    環境:Tomcat 5.5MySql 5.0

    1.1. 新建工程

    操作:[Menu] File/New/Web Project

    工程名:login

    2. Struts 部分


    2.1. 添加 Struts 功能支持

    操作:[Menu] MyEclipse/Project Capabilities/Add Struts Capabilities

     

    2.2. 創建 ActionForm 類

    操作:[Ctrl+N] MyEclipse/Web-Struts/Struts 1.2 Form

    類名:LoginForm

    在 “Form Properties” 選項卡為 loginForm 新增兩個屬性:username、password;

    在 “JSP” 選項卡鉤選 “Create JSP form” 選項,將新建路徑改為 “/login.jsp”(login.jsp文件將被自動創建)。

    2.3. 創建 Action 類

    操作:[Ctrl+N] MyEclipse/Web-Struts/Struts 1.2 Action

    類名:LoginAction

    在 “Form” 選項卡的 “Name” 項選擇 “loginForm”,”Input Source” 項輸入 “/login.jsp”。

    2.4. 創建 index.jsp 文件

    如果沒有,創建 index.jsp 文件,并添加一個指向 login.jsp 的鏈接:<a href=”login.jsp”>Login</a>

    2.5. 創建Forword類

    操作:[Ctrl+N] MyEclipse/Web-Struts/Struts 1.2 Forword

    類名:indexForword

    “Name” 項輸入 “indexForword” ,”Path” 項輸入 “/index.jsp” 。

    2.6. 修改 LoginAction.java 文件

    修改 LoginAction 類的 execute 方法:

    public class LoginAction extends Action {

    public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) {
    LoginForm loginForm = (LoginForm) form;
    String username=loginForm.getUsername();
    String password=loginForm.getPassword();
    if(username.equals(”test”)||password.equals(”test”)){
    return mapping.findForward(”indexForword”);
    }else{
    return mapping.getInputForward();
    }
    }
    }

    2.7. 修改 login.jsp 文件

    修改 <html:form> 標簽:<html:form action=”/login”>

    2.8. 測試

    操作:[Menu] Run/Run,選擇 MyEclipse Server Application 方式運行

    要正常執行Run操作,需先安裝 Tomcat5.5 。

    點擊 index.jsp 頁面的 “Login” 鏈接,跳轉到 login.jsp 頁面。在 login.jsp 頁面輸入 “test/test”,應該會登錄成功,然后跳轉到 index.jsp 頁面;輸入 “test/123″ ,應該保持在 login.jsp 頁面。

    如果測試成功,證明 Structs 運行正常。

    3. Spring 部分


    3.1. 添加 Spring 功能支持

    操作:[Menu] MyEclipse/Project Capabilities/Add Spring Capabilities

    Spring 版本( Spring version )選擇 “Spring 1″;

    開發包(libraries)選擇 “Spring 1.2 AOP Libraries、Spring 1.2 Core Libraries、Spring 1.2 Persistence Core Libraries、Spring 1.2 Persistence JDBC Libraries” 四項;

    JAR Library Installation 選擇 “copy checked…” ,”Library Folder” 項選擇 “/WebRoot/WEB-INF/lib”(這樣的話所需的類庫都將拷貝到項目目錄,方便以后的布署)。

    點擊 “下一步(Next)” 創建配置文件,修改文件路徑(Folder)到 “WebRoot/WEB-INF” 目錄(以便和Struts配置文件一起管理),文件名稱為默認的”applicationContext.xml”。

    點擊 “完成(Finish)” 。

    3.2. 配置 struts-config.xml 文件

    添加 Spring 插件(在 <message-resources> 標簽后面添加):

    <plug-in className=”org.springframework.web.struts.ContextLoaderPlugIn”>
    <set-property property=”contextConfigLocation” value=”/WEB-INF/applicationContext.xml” />
    </plug-in>

    修改 LoginAction 的配置(只需修改 type 屬性):

    <action-mappings >
    <action
    attribute=”loginForm”
    input=”/login.jsp”
    name=”loginForm”
    path=”/login”
    scope=”request”
    type=”org.springframework.web.struts.DelegatingActionProxy” />

    </action-mappings>

    綠色字體部份為被修改過的內容,這里將使用 spring 的代理器 DelegatingActionProxy 來對 Action 進行控制。

    3.3. 修改 Spring 配置文件 applicationContext.xml

    <?xml version=”1.0″ encoding=”UTF-8″?>
    <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”>

    <beans>
    <bean name=”/login” class=”com.login.struts.action.LoginAction” singleton=”false”></bean>
    </beans>

    綠色字體是關于接受和處理 Action 控制權的配置內容,”com.login.struts.action.LoginAction” 即為原 struts 里的配置。

    3.4. 測試

    同上一次測試。測試成功證明 Spring 運行正常。

    4. Hibernate 部分

    下面開始 Hibernate 部分,將原例修改為使用數據庫進行用戶名/密碼驗證。

    4.1. 創建 mysql 數據庫和表

    添加表的代碼如下:

    CREATE TABLE user_table(
    ID int NOT NULL auto_increment,
    USERNAME varchar(45) NOT NULL default ”,
    PASSWORD varchar(45) NOT NULL default ”,
    PRIMARY KEY (ID)
    )

    再添加一條記錄:

    insert into user_table (USERNAME,PASSWORD) values (’test’,'test’)

    4.2. 創建 MyEclipse 數據庫驅動(DB Driver)

    操作:[Menu] MyEclipse/Prefrences/MyEclipse/Database Explorer/Database Driver/DB Brower

    在 DB Brower 的菜單中選擇 “New” ,”Driver Name” 項輸入 “login-conn” ,”Connection URL” 項輸入 “jdbc:mysql://localhost:3306/test” ,然后輸入正確的用戶名(User Name)和密碼(Password)按實際情況輸入;

    在 “Driver JARs” 項添加 “mysql-connector-java-5.0.4-bin.jar” (可從網上下載),在 “Driver classname” 里選擇 “com.mysql.jdbc.Driver” ,其它自選。

    點擊 “完成(Finish)”。

    4.3. 添加 Hibernate 功能支持

    操作:[Menu] MyEclipse/Project Capabilities/Add Hibernate Capabilities

    Hibernate 版本(Hibernate Specification)選擇 “Hibernate 3.1″ ,開發包(libraries)選擇 Hibernate 3.1 Core Libraries 一項;

    JAR Library Installation 選擇 “copy checked…” ,”Library Folder” 選擇 “/WebRoot/WEB-INF/lib” 。

    點擊 “下一步(Next)” 設置配置文件,選擇 “Spring configuration file (applicationContext.xml)” 。

    “下一步(Next)” 設置 Spring-Hibernate,選擇 “Existing Spring configuration file” ,”SessionFactory ID” 項輸入 “sessionFactory” 。

     

    “下一步(Next)” 創建數據源對象,在 Bean Id 中輸入 dataSource,”DataSource” 項選擇 “Use JDBC Dirver” ,DB Driver 項選擇 “login-conn” ,其余項會自動填充;

    記得選中 “Copy DB driver jar(s) to project and add to buidpath” 項,以便將數據連接的庫文件復制到項目,方便以后的布署。

    “下一步(Next)” 創建 SessionFactory 類,”Java package” 項設置為 “com.login.Hibernate” (沒有則點擊”New”按鈕添加),”Class name” 項修改為”SessionFactory” ,Java Compliance Level選擇和創建項目時選擇的Java版本。(本例中并沒有用到SessionFactory類,留作今后擴展)

    點擊 “完成(Finish)”。

    4.4. 創建對象關系映射(ORM)的相關文件

    操作:[Menu] Window/Open Perspective/MyEclipse Database Explorer

    選中 user_table 表,點擊右鍵,在出現的菜單中選擇 “Hibernate Reverse Engnieering” 。

    在彈出的窗口中保持 “Java package” 項為 “com.login” ;

    選中 “Hibernate mapping file (*.hbm.xml) for each databases table” ,并保持 “Update hibernate…” 項選中;

    選中 “Java Data Object” 項,并保持 “Create abstract class” 選中;

    “Base persistent class” 項留空;

    取消 “Java Data Access Object…” 項和 “Use custom templates” 項。

    點擊 “下一步(Next)” ,再點擊 “下一步(Next)” ,在 “Configure reverse engineering details” 頁選中 “user_table” 表,在右邊出現的 “Class Name” 項中輸入 “com.login.User”,其它不變。

    點擊 “完成(Finish)”。

    完成此操作,會在 “com.login” 包下創建三個文件:AbstractUser.java、User.java、User.hbm.xml。

    4.5. 創建 UserDAO.java 接口和 UserDAOImpl.java 類

    UserDAO 和 UserDAOImpl 通過 Hibernate 訪問數據庫。

    UseDAO.java 內容如下:

    package com.login;

    public interface UserDAO {
    public abstract boolean isValidUser(String username, String password);
    }

    UserDAOImpl.java 內容如下:

    package com.login;

    import java.util.List;
    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

    public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
    private static String hql = “from User u where u.username=? “;

    public boolean isValidUser(String username, String password) {
    // 驗證用戶
    List userList = this.getHibernateTemplate().find(hql, username);
    if (userList.size() > 0) {
    return true;
    }
    return false;
    }
    }

    4.6. 修改 LoginAction.java 文件

    使用 UseDAO 對象來驗證:

    package com.login.struts.action;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts.action.Action;
    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import org.apache.struts.action.ActionMapping;
    import com.login.struts.form.LoginForm;
    import com.login.UserDAO;

    public class LoginAction extends Action {
    private UserDAO userDAO;

    public UserDAO getUserDAO() {
    return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
    }

    public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) {

    LoginForm loginForm = (LoginForm) form;
    String username=loginForm.getUsername();
    String password=loginForm.getPassword();

    if( userDAO.isValidUser( username, password ) ){
    return mapping.findForward( “indexForword” );
    }else{
    return mapping.getInputForward();
    }
    }
    }

    綠色字體為修改部分。

    4.7. Spring 的最終配制文件 applicationContext.xml

    <?xml version=”1.0″ encoding=”UTF-8″?>
    <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”>

    <beans>

    <bean id=”dataSource”
    class=”org.apache.commons.dbcp.BasicDataSource”>
    <property name=”driverClassName” value=”com.mysql.jdbc.Driver”></property>
    <property name=”url” value=”jdbc:mysql://localhost:3306/test”></property>
    <property name=”username” value=”root”></property>
    <property name=”password” value=”root”></property>
    </bean>

    <!– 配置sessionFactory, 注意這里引入的包的不同 –>
    <bean id=”sessionFactory” class=”org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
    <property name=”dataSource”>
    <ref local=”dataSource” />
    </property>
    <property name=”mappingResources”>
    <list>
    <value>com/login/User.hbm.xml</value>
    </list>
    </property>
    <property name=”hibernateProperties”>
    <props>
    <prop key=”hibernate.dialect”>org.hibernate.dialect.MySQLDialect</prop>
    <prop key=”hibernate.show_sql”>true</prop>
    </props>
    </property>
    </bean>

    <bean id=”transactionManager” class=”org.springframework.orm.hibernate3.HibernateTransactionManager”>
    <property name=”sessionFactory”>
    <ref local=”sessionFactory” />
    </property>
    </bean>

    <bean id=”userDAO” class=”com.login.UserDAOImpl”>
    <property name=”sessionFactory”>
    <ref local=”sessionFactory” />
    </property>
    </bean>

    <bean id=”userDAOProxy” class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
    <property name=”transactionManager”>
    <ref bean=”transactionManager” />
    </property>
    <property name=”target”>
    <ref local=”userDAO” />
    </property>
    <property name=”transactionAttributes”>
    <props>
    <prop key=”insert*”>PROPAGATION_REQUIRED</prop>
    <prop key=”get*”>PROPAGATION_REQUIRED,readOnly</prop>
    <prop key=”is*”>PROPAGATION_REQUIRED,readOnly</prop>
    </props>
    </property>
    </bean>

    <bean name=”/login” class=”com.login.struts.action.LoginAction” singleton=”false”>
    <property name=”userDAO”>
    <ref bean=”userDAOProxy” />
    </property>
    </bean>

    </beans>

    4.8. 測試

    同第一次測試。 

    posted @ 2008-07-09 14:13 飛飛 閱讀(3468) | 評論 (2)編輯 收藏

    在spring2.0中,bean沒有“singleton”這個屬性,而是在“scope”中對它進行設定。“scope”可以設定為“singleton”和“prototype”默認情況下是“singleton”即和原先的“singleton=true”性質一樣,如果要實現單例模式則將“scope”設定為“prototype”,即和原先版本的“singleton=false”一樣。參考文檔鏈接地址:http://www.springframework.org/schema/beans/spring-beans-2.0.xsd



    根據用戶名和密碼進行校驗的方法
     public boolean verify(String userName, String userPwd) {
      final String HQL="FROM UserTable u where u.userName=? and u.userPwd=?";
      String[] hqlParameter=new String[2];
      hqlParameter[0]=userName;
      hqlParameter[1]=userPwd;
      List list=this.getHibernateTemplate().find(HQL,hqlParameter);
      if(list.size()>0){
       return true;
      }
      
      return false;
     }
    posted @ 2008-07-09 13:03 飛飛 閱讀(2961) | 評論 (0)編輯 收藏

    mysql-administrator的安裝與使用(圖文)
      
    準備工作
    在D盤建立一個mysql-software的目錄,把剛才下載的 mysql-administrator-1.0.19-win-noinstall.zip 復制到這個子目錄中,解壓,得到一個 MySQL Administrator 1.0 的目錄。
    同樣如此操作 mysql-query-browser-1.1.5-win-noinstall.zip,得到一個 MySQL Query Browser 1.1 的目錄。
      
    啟動服務
    ·
    雙擊D:mysql-softwareMySQL Administrator 1.0 目錄下的 MySQLSystemTrayMonitor.exe,這時會在任務欄右側出現一個圖標。點擊“Start Instance”,運行MySQL。

    ·
    然后雙擊 D:mysql-softwareMySQL Administrator 1.0 目錄中的 MySQLAdministrator.exe,或者直接點擊上面右鍵菜單中的“MySQL Administrator ”:

    ·
    創建一個連接名,可以隨便填,這里是“mxj”,用戶名:root,密碼空著。這是因為mysql默認有一個沒有密碼的root帳號。點擊“OK”,出現管理窗口:

    這沒什么好說的,英文也很簡單。只談談上面勾選的兩項。
    更改密碼

    好了,我的root帳號的密碼設置為:javamxj    最后,點擊“Apply Change”。
    ● 初始的

    數據庫



    上圖可以看到,初始有兩個

    數據庫

    ,mysql庫中含有各種配置信息,不要在這個庫中進行表操作。
    test庫初始是空的。另外,建立表時,不要和mysql庫中的表名取名相同,以免沖突。
    數據創建與查詢(兼談談字符編碼)
    ·
    現在來到查詢瀏覽器,還是右擊右下角“MySQL System Tray Monitor”圖標,從中選擇“MySQL Query Browser”,因為已經更改過root的密碼,所以要填入新密碼。

    ·
    進入主界面,右擊test

    數據庫

    ,創建一個新表。

    ·
    如下簡單創建一個表

    ·
    切換到“Table Options”:

    如果了解

    數據庫

    的話,這些應該是很熟悉的,不多說了。注意字符設置默認是“Latin1”(保存改變,再次切換到這一欄,就能看到了)。
    ·
    填入一些測試數據:

    ·
    關閉“MySQL Query Browser”,再重新打開它,切換到testtable表,看到了沒有?剛才輸入的中文變成了“??????”,為什么呢? 再次切換到“Table Options”:

    知道為什么了吧,原來默認字符是“latin1”,因為MySQL是瑞典一家公司的產品。中國人看來要努力了!
    ● 解決方法:
    ·
    停止MySql服務,關閉所有與MySql相關的程序,打開Windows的系統安裝目錄下的 my.ini 文件,如下修改:
    E:WINDOWSmy.ini

    [WinMySQLAdmin]
      
    Server

    =D:/mysql/bin/mysqld-nt.exe
      
    [mysqld]
      
    basedir
    =D:/mysql
      
    datadir
    =D:/mysql-data/data
      
    default-character-set
    =gbk
      
    [client]
      
    default-character-set
    =gbk
    添加的兩條語句的含義是在客戶端和服務端都使用GBK字符集進行編碼。
    保存后,重新激活 MySql 服務,打開“MySQL Query Browser”,再次創建一個表,輸入中文,一切OK!

    備份時會出錯,以下日志:
    ----------------------------------------
    2008-07-03 14:18 - Backup started.
    Preparing backup for for profile mysql.
    Connections loaded from file C:\Documents and Settings\Administrator\Application Data\MySQL\mysqlx_user_connections.xml.
    Connection NewConnection selected.
    Cannot connect to MySQL Server. Access denied for user 'root'@'localhost' (using password: NO) (Error Number 1045)

    在mysqlx_user_connections.xml.文件中加個密碼進去
    <?xml version="1.0"?>
    <user_connections>
      <last_connection>0</last_connection>
      <password_storage_type>2</password_storage_type>
      <user_connection>
        <connection_name>NewConnection</connection_name>
        <username>root</username>
        <hostname>127.0.0.1</hostname>
        <port>3306</port>
        <schema>test</schema>
        <advanced_options/>
        <storage_path></storage_path>
        <notes></notes>
        <connection_type>0</connection_type>
        <storage_type>1</storage_type>
        <password_storage_type>2</password_storage_type>
        <password>root</password>
      </user_connection>
    </user_connections>

    但是在備份的時候還是會出現錯誤

    根據提示選擇open options 選擇 password storage
    OK
    電腦每次自己啟動MySQLSystemTrayMonitor 就會在定制的時間備份數據庫

    Your account information:
    Name: fei zhao
    Email: feifeixia2003@yahoo.com.cn
    Password: nehaifrowa
    You can log in to your new account and edit your profile options at:
      http://www.mysql.com/login.php
    posted @ 2008-07-03 13:54 飛飛 閱讀(10076) | 評論 (1)編輯 收藏

    http://www.net.cn/static/customercare/support/demo/outlook/outlook.htm
    fei.zhao@centralsoft.com.cn
    211.155.226.126
    posted @ 2008-07-02 09:22 飛飛 閱讀(970) | 評論 (0)編輯 收藏

    有些事情現在已經很容易被忘記了,但是在開發原創的 Mac OS 的時候,業界到處出現新的圖形用戶接口(GUI),人們所做的工作差別相當小。Macintosh 的設計團隊在很多事情上是正確的,這很大程度上是因為他們在自己正在干什么這個問題上付出了難以想像的思考。雖然我要為 Internet Developer(英特網開發者)書寫一些腳本方面的集體思想,但我還是想去看一些過去的 Macintosh 人機界面指南,并且看看這些指導原則如何才能用到 Web 界面上,我認為這是很值當的。我很少去找可以拷貝的具體部件,而更多地尋找這個以友好聞名的界面后面隱藏的設計原則。

    原則之一就是無模式。這個原則打動了我,因為它特別適合于 Web。正如 Mac 的設計者描述的那樣,模式界面(在這種界面下,您能做什么取決于您當前處于什么模式下)會“把用戶鎖定在一個操作上,用戶在該操作完成之前不允許進行其它任何操作”。使用單純的老版本HTML時,從某種意義上看,所有界面都是模式的,進行任何修改都需要裝載一個新的頁面。舉例來說,假定您在填充一個表單時需要一些幫助,則您必須轉到包含幫助信息的新頁面,然后再回到原來的頁面,以完成表單的填寫。

    換句話說,您或者處于“幫助”模式,或者處于“表單填寫”模式。這凸顯了 Web 的兩個主要的限制:無態(即當點擊幫助連接時,您在表單中已經輸入的信息將會丟失)和遲延(即您必須等待頁面裝載)。因此我決定寫一點腳本來幫助處理這些問題。這些腳本通過動態 HTML (DHTML)技術在您點擊連接時彈出一個帶有幫助信息的方框。在我的演示中,就是使用它們來彈出與表單填寫相關的上下文幫助信息。這些腳本也可以用在別的地方,比如彈出一篇論文的術語定義。上述的兩種情況都以合理的方式給出了上下文相關的信息,即無模式的方式。同時,這個解決方案也避免了無態和遲延的問題。

    實際上,我寫的這些基本函數可以用在任何需要在頁面上移動和改變對象可視性的地方。我做了一個快速下拉菜單的實例,就是為了演示同樣這些代碼的另外一種使用方式,您可能會用得到。

    您可能會擔心有人還在使用版本比較老的瀏覽器,對此,我們可以相當輕松地使這些腳本自然地回退到原來的狀態,使那些使用老版本瀏覽器的用戶可以簡單地從一個單獨的頁面上獲得信息。我將在下面的“如何使用腳本”的部分中解釋如何實現這個目標。

    腳本的目標

    這個腳本將創建動態菜單和彈出式對象。它包括一些跨瀏覽器的基本函數,用于移動和改變DHTML對象的可視性。在 Netscape 4.x 中,一個 DHTML 對象是一個通過絕對位置定位的 DIV,而對 Safari,Internet Explorer 4 和 5,或者 Netscape 6 來說,則是任何 HTML 元素。這些函數可以被用在大量的 DHTML 應用中;這里還給出的兩個實例,向您演示如何創建一個彈出式的提示(tip)和下拉式菜單。腳本中的主要函數如下:

    • changeObjectVisibility,用來翻轉一個 DHTML 對象的可視性。
    • moveObject,用來在瀏覽器窗口中把一個 DHTML 對象移動到特定的位置上。
    • getStyleObject,這個函數通過獲得一個風格對象的引用簡化了跨瀏覽器的 DTHML,我們可以從這個對象中讀取屬性,或者進行屬性設定,包括位置,可視性,顏色,尺寸,等等。

    編碼的挑戰

    遺憾的是,由于長期以來瀏覽器都是由各個廠商自行實現,所以書寫跨瀏覽器和跨平臺的 DHTML 通常是拜占庭式的條件分支。為任何一個瀏覽器書寫這些腳本都是非常輕松的;為了使它們工作在 Netscape 4 及其升級版本,以及工作在 Internet Explorer 4 及其升級版本上,事情就要復雜一些了;而使它們可以回退到比較老版本的瀏覽器的狀態,又增加了更多的復雜度。問題在于各個瀏覽器在如何尋找和操作 Web 頁面上的對象方面都有很多獨特之處,雖然我們對這種狀態已經比較熟悉了。為了方便,我寫了處理這些條件分支的代碼。

    這些函數中有一些功能不能工作在更老一些的瀏覽器上,比如 Netscape 3。然而,使這些功能自然地退化并補臺困難。您只需進行如下操作:

    • 直接把這些腳本包含在頁面上,而不是使用連接的 .js 文件。
    • 只在提供相關支持的瀏覽器上使用 JavaScript 進行彈出式的 DIV 的輸出。實現這個控制的代碼大致如下:
      if(document.getElementById || document.all
          || document.layers) {
          // write out div tag with document.write
          }

    我發現的最大挑戰是必須考慮瀏覽器處理事件的不同方式。事件發生時(比如 click 或者 mouseover 事件)光標的位置存儲在一個事件對象中,而不同瀏覽器對事件對象的處理有輕微的不同。當事件發生時,Netscape 4 和6都產生一個新的事件對象,您可以把這個對象作為一個參數傳遞到函數中;而 Internet Explorer 則使用一個獨立的全局 window.event 對象。對于這個問題,我在拋棄幾個現在看來很草率的解決方案之后,發現把事件對象顯式地傳遞給函數的做法可以適用于這兩種瀏覽器:

    <a href="#" onclick="showPopup('popupName',
    event);">click</a>

    請注意,在事件邊上少了引號標識。那是因為它是一個對象,而不是文本。現在,在您的函數中就可以以如下方式使用傳入的事件對象了:

    function showPopup(nameOfPopup, eventObject) {
    alert(eventObject.clientX);
    }

    一旦把對象傳遞給函數,您就可以通過讀取 pageXpageY 屬性(Netscape 4 和 6)或者 clientXclientY 屬性(IE 4+)來獲得光標的位置。然而請注意,clientXclientY 屬性并沒有考慮頁面可能被滾動的情況,因為這兩個坐標是相對于窗口的左上角的,而不是整個文檔。為了解決這個問題,我們加上 IE 的 document.body.scrollLeft document.body.scrollTop 屬性的值。如果您感興趣的話,事件對象還有一連串有用的屬性,包括一個事件觸發對象的引用(在 IE 上是 srcElement,而在 Netscape 上則是 target)。

    把事件對象作為參數進行傳遞的唯一麻煩是在不支持事件對象的老版本瀏覽器上不能工作。為了繞開這個問題,我們在 popup.js 文件中包含一個函數,該函數為那些不存在事件對象的瀏覽器創建一個假的對象,在裝載文檔時運行:

    function createFakeEventObj() {
    // create a fake event object for older browsers
    //to avoid errors in function call when we
    //need to pass the event object
    if (!window.event) {
    window.event = false;
    }
    }

    這個函數把 window.event 設定為 false(假)。這樣以后,我們就可以在使用之前進行檢測,看看是否存在真正的事件對象。

    在 Mac 版的 Internet Explorer 5 上有一個問題,即當彈出層出現在文本的上方時,只有部分內容可以被顯示。但是當我移動 DIV 標識,使之成為文檔體的第一個元素時,這個問題神秘地消失了。

    還是在 Mac 版的 IE 5 上,由于某些原因,document.onclick 事件只有在頁面上存在實際文本時才能被觸發。為了繞過這個缺陷(以便使您可以通過點擊窗口中的任意位置來關閉窗口),我在頁面中增加了一個不包含任何內容的,通過絕對位置定位的 DIV,然后用 JavaScript 來改變這個 DIV 的尺寸,使之覆蓋整個窗口。相關的代碼大致如下:

    function resizeBlankDiv() {
    // resize blank placeholder div so IE 5
    // on mac will get all clicks in window
    if ((navigator.appVersion.indexOf('MSIE 5') != -1)
    && (navigator.platform.indexOf('Mac') != -1)
    && getStyleObject('blankDiv')) {
    getStyleObject('blankDiv').width =
    document.body.clientWidth - 20;
    getStyleObject('blankDiv').height =
    document.body.clientHeight - 20;
    }
    }

    遺憾的是,如果瀏覽器的尺寸被改變了,則只有一種方法可以恢復尺寸,即重新裝載整個文檔(您可能認為,只要用 window.onresize 事件就可以了。然而由于這個事件在窗口的尺寸真正被改變之前就已經發生了,所以采用這種方法最終會產生不必要的滾動條)。為了恢復頁面尺寸,我們又寫了一個函數,在窗口尺寸被改變的任何時候,該函數可以從 Mac 平臺上的 IE5 的緩存中重新裝載頁面。

    在 Mac 版的 Internet Explorer 5 上,當您點擊一個連接時,會出現一個絕對大的輪廓,這個輪廓會和將要彈出的內容相重疊。為了解決這個問題,我在連接上增加了一條風格規則:

    .popupLink { outline: none }

    Netscape 4 在 DIV 的命名上有一些怪異的問題。以數字開頭的名稱(比如“1div”),以及有些帶有下劃線的名稱(比如“my_div”)不能轉化為層,因此我通常都避免這兩種情況,把我的 DIV 按類似于 myDiv 或者 div1 的形式來命名。

    Netscape 4 還有一個嚴重的缺陷,即當窗口的尺寸被改變時,所有的風格規則都會丟失。我沒有把修復這個缺陷的代碼包含進來,因為已經有好幾個這樣的代碼公布出來了,比如 Webmonke 上的這個.

    最后,在 Netscape 4 中,如果您把 javascript: 放在 hrefs 中,會導致頁面的重新裝載,并把函數的返回值當成頁面的唯一內容顯示出來。因此我們不應該采取下面的方式:

    <a href="javascript:myFunction();">clickme</a>

    而必須采取象下面的做法:

    <a href="#" onclick="myFunction();
    return false;">clickme</a>

    實際上,這也是確保您的腳本在不能運行這些函數的瀏覽器上自然退化的好方法。請注意“return false”這行代碼,它使瀏覽器停止裝載 href 參數指定的URL。這樣,如果瀏覽器中 JavaScript 被關閉,或者瀏覽器不能處理 JavaScript,則您可以提供一個不同的頁面;但是如果這里的函數可以運行,則連接不會被打開。

    在這個演示中,我們討論的更深一些:

    <a href="#" onclick="return
    !showPopup('nameFieldPopup', event);">
    clickme</a>

    我們不去深入到所有的細節,只是大概看看這行代碼,它的意思是運行 showPopup 函數,然后返回該函數返回值的非。那樣,如果 showPopup 返回 true(意思是它成功顯示了彈出層),我們就把 false 返回給連接,這樣連接就不會改變頁面。另外一方面,如果 showPopup 返回 false(意思是它不能顯示彈出層),則我們就繼續執行腳本,跟著連接進入到一個獨立的頁面,該頁面具有和彈出層相同的信息。這個邏輯看起來可能有點混淆,但是只要記住一條就可以了:如果您返回 false,連接就不起作用了。

    使用腳本

    如果要使用這些腳本來實現彈出機制,請按照如下這些步驟來進行:

    • 如果要進行層的彈出,則需要把層工具和實現彈出機制的腳本文件都包含進您的頁面。這可以通過把下面兩條語句包含到您的文檔頭部來實現:
       <script src="utility.js"></script>
          <script src="popup.js"></script>
    • 確保有可以被彈出的 DIV。這些 DIV 必須被絕對定位,并且在開始是應該被隱藏。例如:
      <DIV onclick="event.cancelBubble = true;"
          class=popup id=nameOfPopup>
          Popup text goes here.<br>
          <a href="#" onclick="hideCurrentPopup();
          return false;">
          You can include a link like this to
          close the DIV if you like
          </a>
          </DIV>
      確保在DIV中包含onclick="event.cancelBubble = true;"這行代碼。它告訴JavaScript在您點擊DIV時不要把點擊事件傳遞給頁面中的其它對象。如果省略這行代碼,則彈出層在被點擊時就會關閉(對于大多數瀏覽器來說),因為我們已經設定了一個關閉彈出層的事件處理函數。把這行代碼包含到頁面中的基本目的是告訴瀏覽器“當人們點擊除了彈出層自身(或者打開彈出層的原始連接)之外的任何地方時,關閉彈出層”。
    • 如果要改變彈出層的外觀,請編輯風格表單中的.popup的風格規則。
    • 在每一個應該觸發彈出層的地方調用showPopup函數,把nameOfPopup改為您希望顯示的彈出層名稱(但是把它放在單引號中):
      <a 
          onclick="return !showPopup
          ('nameOfPopup', event);">
          clickme</a>
      如果您希望當鼠標在連接上滾動時出發彈出層,則只要修改觸發事件就可以了:
      <a 
          onmouseover="showPopup('nameOfPopup', event);"
          onmouseout="hideCurrentPopup();">clickme
          </a>
    • (可選)修改popup.js文件中的兩個變量,這兩個變量用來控制彈出層出現的位置,該位置是相對于當前光標位置的:
      var xOffset = 30;
          var yOffset = -5;

    下面對相關的函數逐一進行說明:

    • changeObjectVisibility(objectId, newVisibility):調用這個函數時,objectId 應該是您希望顯示或者隱藏的對象名稱。函數希望這個參數是文本類型的,因此您需要把它包含在引號中。newVisibility 參數的值或者是 visible(可視)或者是 hidden(隱藏)。再次說明一下,這個值是一個字符串類型的,因此需要把它包含在引號中。下面這個實例把一個名為 myBigLayer: 的對象隱藏起來:
      changeObjectVisibility('myBigLayer', 'hidden')
    • moveObject(objectId, newXCoordinate, newYCoordinate):同樣的,objectId 應該是您希望移動的對象名稱。它是一個文本類型的參數,因此應該放在引號里面。newXCoordinatenewYCoordinate a 是數字類型的(因此沒有引號),描述您希望把對象移動到什么地方。因此,如果要把 myBigLayer 對象移動到距離窗口左邊 300 p 像素,距離窗口上邊10像素的位置,書寫如下代碼就可以了:
      moveObject('myBigLayer', 300, 10)
    • getStyleObject(objectId):上述兩個函數都使用這個函數來把對象的名稱轉變為屬于該對象的風格對象的引用。對于 Netscape 4+ 和 IE 4+ 兩款瀏覽器來說,這個函數都能返回正確的引用,因此您不必擔心瀏覽器在工作方式上的差別。(請注意:有一種情況在 Netscape 4 上處理不了,那就是聚集層,因此您必須避免把層放到其它層上)。

      在您需要改變對象的 CSS 屬性的任何時候,您都可以脫離這里描述的上下文來使用這個函數。例如,假定我們要給 myBigLayer 設定一個綠的背景色,可以書寫如下代碼:

      ar myBigLayerStyleObject =
          getStyleObject('myBigLayer');
          myBigLayerStyleObject.backgroundColor =
          'green';

      Or, for shorthand, you could just do this:

      getStyleObject('myBigLayer').backgroundColor
          = 'green';






      utility.txt

      // Copyright ?2000 by Apple Computer, Inc., All Rights Reserved.
          //
          // You may incorporate this Apple sample code into your own code
          // without restriction. This Apple sample code has been provided "AS IS"
          // and the responsibility for its operation is yours. You may redistribute
          // this code, but you are not permitted to redistribute it as
          // "Apple sample code" after having made changes.
          //
          // ************************
          // layer utility routines *
          // ************************
          function getStyleObject(objectId) {
          // cross-browser function to get an object's style object given its id
          if(document.getElementById && document.getElementById(objectId)) {
          // W3C DOM
          return document.getElementById(objectId).style;
          } else if (document.all && document.all(objectId)) {
          // MSIE 4 DOM
          return document.all(objectId).style;
          } else if (document.layers && document.layers[objectId]) {
          // NN 4 DOM.. note: this won't find nested layers
          return document.layers[objectId];
          } else {
          return false;
          }
          } // getStyleObject
          function changeObjectVisibility(objectId, newVisibility) {
          // get a reference to the cross-browser style object and make sure the object exists
          var styleObject = getStyleObject(objectId);
          if(styleObject) {
          styleObject.visibility = newVisibility;
          return true;
          } else {
          // we couldn't find the object, so we can't change its visibility
          return false;
          }
          } // changeObjectVisibility
          function moveObject(objectId, newXCoordinate, newYCoordinate) {
          // get a reference to the cross-browser style object and make sure the object exists
          var styleObject = getStyleObject(objectId);
          if(styleObject) {
          styleObject.left = newXCoordinate;
          styleObject.top = newYCoordinate;
          return true;
          } else {
          // we couldn't find the object, so we can't very well move it
          return false;
          }
          } // moveObject
          
      popup.txt
      // Copyright ?2000 by Apple Computer, Inc., All Rights Reserved.
          //
          // You may incorporate this Apple sample code into your own code
          // without restriction. This Apple sample code has been provided "AS IS"
          // and the responsibility for its operation is yours. You may redistribute
          // this code, but you are not permitted to redistribute it as
          // "Apple sample code" after having made changes.
          // ********************************
          // application-specific functions *
          // ********************************
          // store variables to control where the popup will appear relative to the cursor position
          // positive numbers are below and to the right of the cursor, negative numbers are above and to the left
          var xOffset = 30;
          var yOffset = -5;
          function showPopup (targetObjectId, eventObj) {
          if(eventObj) {
          // hide any currently-visible popups
          hideCurrentPopup();
          // stop event from bubbling up any farther
          eventObj.cancelBubble = true;
          // move popup div to current cursor position
          // (add scrollTop to account for scrolling for IE)
          var newXCoordinate = (eventObj.pageX)?eventObj.pageX + xOffset:eventObj.x + xOffset + ((document.body.scrollLeft)?document.body.scrollLeft:0);
          var newYCoordinate = (eventObj.pageY)?eventObj.pageY + yOffset:eventObj.y + yOffset + ((document.body.scrollTop)?document.body.scrollTop:0);
          moveObject(targetObjectId, newXCoordinate, newYCoordinate);
          // and make it visible
          if( changeObjectVisibility(targetObjectId, 'visible') ) {
          // if we successfully showed the popup
          // store its Id on a globally-accessible object
          window.currentlyVisiblePopup = targetObjectId;
          return true;
          } else {
          // we couldn't show the popup, boo hoo!
          return false;
          }
          } else {
          // there was no event object, so we won't be able to position anything, so give up
          return false;
          }
          } // showPopup
          function hideCurrentPopup() {
          // note: we've stored the currently-visible popup on the global object window.currentlyVisiblePopup
          if(window.currentlyVisiblePopup) {
          changeObjectVisibility(window.currentlyVisiblePopup, 'hidden');
          window.currentlyVisiblePopup = false;
          }
          } // hideCurrentPopup
          // ***********************
          // hacks and workarounds *
          // ***********************
          // initialize hacks whenever the page loads
          window.onload = initializeHacks;
          // setup an event handler to hide popups for generic clicks on the document
          document.onclick = hideCurrentPopup;
          function initializeHacks() {
          // this ugly little hack resizes a blank div to make sure you can click
          // anywhere in the window for Mac MSIE 5
          if ((navigator.appVersion.indexOf('MSIE 5') != -1)
          && (navigator.platform.indexOf('Mac') != -1)
          && getStyleObject('blankDiv')) {
          window.onresize = explorerMacResizeFix;
          }
          resizeBlankDiv();
          // this next function creates a placeholder object for older browsers
          createFakeEventObj();
          }
          function createFakeEventObj() {
          // create a fake event object for older browsers to avoid errors in function call
          // when we need to pass the event object to functions
          if (!window.event) {
          window.event = false;
          }
          } // createFakeEventObj
          function resizeBlankDiv() {
          // resize blank placeholder div so IE 5 on mac will get all clicks in window
          if ((navigator.appVersion.indexOf('MSIE 5') != -1)
          && (navigator.platform.indexOf('Mac') != -1)
          && getStyleObject('blankDiv')) {
          getStyleObject('blankDiv').width = document.body.clientWidth - 20;
          getStyleObject('blankDiv').height = document.body.clientHeight - 20;
          }
          }
          function explorerMacResizeFix () {
          location.reload(false);
          }
          
      彈出式幫助的實例

      <HTML><HEAD>

      <script src="utility.txt"></script>

      <script src="popup.txt"></script>


      <STYLE>

      .popupLink { COLOR: red; outline: none }

      .popup { POSITION: absolute; VISIBILITY: hidden; BACKGROUND-COLOR: yellow; LAYER-BACKGROUND-COLOR: yellow; width: 200; BORDER-LEFT: 1px solid black; BORDER-TOP: 1px solid black; BORDER-BOTTOM: 3px solid black; BORDER-RIGHT: 3px solid black; PADDING: 3px; z-index: 10 }

      </STYLE>


      <BODY bgcolor="#ffffff">


      <!-- keep the popup divs as the first things on the page or else MSIE 5 on the mac sometimes has trouble rendering them on top of text -->

      <DIV onclick='event.cancelBubble = true;' class=popup id=nameFieldPopup>Hi, [your name here]! We need to know your <b>name</b> so we can address you a bit more personally. [<a class=closeLink href='#' onclick='hideCurrentPopup(); return false;'>close this tip</a>]</DIV>

      <DIV onclick='event.cancelBubble = true;' class=popup id=emailFieldPopup>Well, yeah, you could put in a fake <b>email address</b>, but then we couldn't send you occasional updates. Oh and, um, we promise not to spam you. [<a class=closeLink href='#' onclick='hideCurrentPopup(); return false;'>close this tip</a>]</DIV>


      <!-- begin body of document -->

      <form>
          <p>Fill in the form:</p>


          <P>Name: <input type=text> [<a href="non_js_help.html" class=popupLink onclick="return !showPopup('nameFieldPopup', event);">help</a>]</P>
          <P>Email: <input type=text> [<a href="non_js_help.html" class=popupLink onclick="return !showPopup('emailFieldPopup', event);">help</a>]</P>
      </form>

       


      <!-- leave this blank div in here to make sure you can click anywhere on the document for MSIE 5 mac -->
      <div id="blankDiv" style="position: absolute; left: 0; top: 0; visibility: hidden"></div>


      </BODY></HTML>
      http://www.apple.com.cn/developer/internet/webcontent/hideshow_layer.html









    posted @ 2008-06-24 17:30 飛飛 閱讀(871) | 評論 (0)編輯 收藏

       在怎合struts+hibernate+spring時,Tomcat出現了Error Listenerstart錯誤碼,郁悶的很,在網上找了很多的資料,提問的不少,但都沒有很標準的解釋以用解決的辦法,有的說是jar包的版本沖突,有的說是Tomcat的自身問題,各解釋都有,基本上所有的方法我都試過了。就這個問題搞了兩天。終于找到了解決的辦法:在web.xml時將:

    <!-- 使用監聽方式載入Spring上下文 -->
    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    改為:

    <!-- 使用監聽方式載入Spring上下文 -->
    <servlet>
       <servlet-name>SpringContextServlet</servlet-name>
       <servlet-class>
        org.springframework.web.context.ContextLoaderServlet
       </servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
       <servlet-name>SpringLog4jConfigServlet</servlet-name>
       <servlet-class>
        org.springframework.web.util.Log4jConfigServlet
       </servlet-class>
    </servlet>
    <servlet>
       <servlet-name>web</servlet-name>
       <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
       </servlet-class>
    </servlet>

    posted @ 2008-06-22 11:46 飛飛 閱讀(7568) | 評論 (1)編輯 收藏

    一、在Myeclipse軟件中部署

    1、 Myeclipse中,創建好工程后,在Myeclipse菜單欄中選擇 Windows -> Preferences -> Myeclipse -> Tomcat5,選擇"Enable";Tomact Home Directory要選擇你機器上Tomcat所安裝的目錄。然后,再Windows -> Preferences -> Myeclipse -> Tomcat5 ->JDK,確保這個是有對應的jdk版本,若沒有,則通過"Add"添加其安裝路徑。ok

    2、選擇工具欄上的 按鈕,在”Project”中選擇你要部署的工程,然后”Add”,再選擇”Tomcat”Finish

    3、 在工具欄上選擇 ,啟動Tomcat

    4、 運行程序。在IE中輸入http://localhost:8080/aa/WebRoot/index.jsp(aa為工程名字)

    二、在Tomcatserver.xml配置文件中部署

    1、在Tomcat下,找到conf文件下的server.xml,打開。

    2、在<Host></host>之間加上如下代碼:

    1 
    2 <Context path="/虛擬目錄名" docBase="目標目錄位置" debug="0" reloadable="true" >
    3 </Context>

    (嚴格區分大小寫,當path=""時,此時的虛擬目錄直接為root--->http://localhost:8080/)
           
    參數:

             path:表示在瀏覽器中輸入http://localhost:8080/虛擬目錄名

             docBase:表示你的程序包的物理絕對路徑,默認的絕對路徑是     %tomcat_home%/webapps

             reloadable :為true,則tomcat會自動檢測應用程序的/WEB-INF/lib /WEB-INF/classes目錄的變化,自動裝載新的應用程序,我們可以在不重起tomcat的情況下改變應用程序;為false則不自動加載。

     (我覺得這種部署方法就好在這里,可以不用重新啟動Tomcat。不知道前一種方法是不是在哪個地方進行配置即可實現同樣的效果。若有,請高人指點!)

    示例:

    1        
    2 <!-- 我的自定義目錄-->
    3 <Context path="/wess" debug="0" docBase="C:\Documents and Settings\tt\workspace\Welcome_SS\WebRoot" reloadable="true">
    4 </Context> 
    5 4

    3、 啟動Tomcat

    Myeclipse工具欄上選擇 ,啟動Tomcat。或者在Tomcat下,找到bin文件下的startup.bat,打開進行啟動。

    4、 運行程序。在IE地址中輸入http://localhost/wess/index.jsp(引用上面示例配置時的情況)

    附:

        在lib下的struts-config.xml可以添加下面三句進行主頁默認的配置,即在IE中只需輸入到主頁所在目錄,而不必寫出主頁。如上面的配置就可只輸入http://localhost/wess

     <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

     

    posted @ 2008-06-22 09:07 飛飛 閱讀(396) | 評論 (1)編輯 收藏

    僅列出標題
    共12頁: First 上一頁 4 5 6 7 8 9 10 11 12 下一頁 
    主站蜘蛛池模板: 亚洲一区爱区精品无码| 亚洲av无码不卡私人影院| 亚洲成AV人片在线观看ww| 三上悠亚电影全集免费| 亚洲一区二区三区乱码A| 精品久久久久久国产免费了| 国产亚洲日韩一区二区三区| 怡红院免费的全部视频| 国产亚洲美女精品久久久久狼| 免费萌白酱国产一区二区三区| 亚洲人成人网站色www| 国产亚洲免费的视频看| 亚洲色偷偷av男人的天堂| 国产四虎免费精品视频| 亚洲色大成网站www久久九| 尤物永久免费AV无码网站| 黄色一级视频免费| 国产亚洲精品xxx| 国产在线jyzzjyzz免费麻豆| 亚洲Av永久无码精品一区二区| 四虎精品亚洲一区二区三区| 天堂在线免费观看| 2019亚洲午夜无码天堂| 免费在线一级毛片| 久久国产精品免费看| 色偷偷女男人的天堂亚洲网| 免费国产小视频在线观看| 两个人看的www免费视频| 亚洲春色另类小说| 免费a级毛片永久免费| 国产偷伦视频免费观看| 亚洲人成伊人成综合网久久| 亚洲国产人成精品| 美丽姑娘免费观看在线观看中文版 | 亚洲香蕉免费有线视频| 亚洲国产精华液2020| 亚洲av无码国产精品色午夜字幕| 最近最好的中文字幕2019免费| 国产精品免费久久久久久久久 | 亚洲永久在线观看| 国产AⅤ无码专区亚洲AV|