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

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

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

    隨筆 - 72  文章 - 28  trackbacks - 0
    <2013年12月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    常用鏈接

    留言簿(4)

    隨筆分類(66)

    隨筆檔案(72)

    文章檔案(19)

    收藏夾

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    在Spring MVC中的配置中一般會遇到這兩個標簽,作為<context:component-scan>的子標簽出現(xiàn)。

    但在使用時要注意一下幾點:

    1.在很多配置中一般都會吧Spring-common.xml和Spring-MVC.xml進行分開配置,這種配置就行各施其職一樣,顯得特別清晰。

    在Spring-MVC.xml中只對@Controller進行掃描就可,作為一個控制器,其他的事情不做。

    在Spring-common.xml中只對一些事務邏輯的注解掃描。

    2.現(xiàn)在給定一個項目包的機構(gòu):

    com.fq.controlller

    com.fq.service

    就先給定這兩個包機構(gòu)

    (1)在Spring-MVC.xml中有以下配置:

     

     

     

    <!-- 掃描@Controller注解 -->
    <context:component-scan base-package="com.fq.controller">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    可以看出要把最終的包寫上,而不能這樣寫base-package=”com.fq”。這種寫法對于include-filter來講它都會掃描,而不是僅僅掃描@Controller。哈哈哈,這點需要注意。他一般會導致一個常見的錯誤,那就是事務不起作用,補救的方法是添加use-default-filters=”false”。

    (2)在Spring-common.xml中有如下配置:

    <!-- 配置掃描注解,不掃描@Controller注解 -->
    <context:component-scan base-package="com.fq">
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    可以看到,他是要掃描com.fq包下的所有子類,不包含@Controller。對于exculude-filter不存在包不精確后都進行掃描的問題。

    posted @ 2015-10-29 10:25 kelly 閱讀(256) | 評論 (0)編輯 收藏


    在Eclipse中創(chuàng)建Maven的Web項目時出現(xiàn)錯誤:An internal error occurred during: “Retrieving archetypes:”. Java heap space,可以通過以下步驟來解決問題。 
    1. 找到Eclipse的根目錄下的eclipse.ini(或myeclipse.ini)文件并打開

    2.修改文件中的以下配置

    -Dosgi.requiredJavaVersion=1.5(可選)

    -Xms512m

    -Xmx1024m

    這是我的配置,大家可以嘗試著修改下,不同的機器配置可能支持的情況不同。

    版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。

    posted @ 2015-10-12 15:09 kelly 閱讀(5315) | 評論 (0)編輯 收藏

    myeclipse自定義java注釋:

    Window->Preference->Java->Code Style->Code Template

    然后展開Comments節(jié)點就是所有需設置注釋的元素

    -----------------

    文件 (Files) 注釋標簽:

    /** 

    @Project : ${project_name}

    @Title : ${file_name}

    @Package ${package_name}

    @Description : ${todo}

    @author shenyanghong ahong2011@gmail.com

    @date ${date} ${time}

    @Copyright : ${year} www.1000chi.com Inc. All rights reserved.

    @version V1.0 

    */

    類 (Types) 注釋標簽(類的注釋):

    /**

      * @ClassName ${type_name}

      * @Description ${todo}

      * @author shenyanghong ahong2011@gmail.com

      * @date ${date}

      * ${tags}

    */

    字段 (Fields) 注釋標簽:

    /** 
    * @Fields ${field} : ${todo}
    */ 


    構(gòu)造函數(shù)標簽:

    /** 
    * <p>Title: </p> 
    * <p>Description: </p> 
    * ${tags} 
    */

     

    方法 (Constructor & Methods) 標簽:

    /** 
    * @Title: ${enclosing_method} 
    * @Description: ${todo}
    * @param ${tags}    
    設定文件 
    * @return ${return_type}    
    返回類型 
    * @throws 
    */

    覆蓋方法 (Overriding Methods) 標簽:

    /* ( 非 Javadoc) 
    * <p>Title: ${enclosing_method}</p> 
    * <p>Description: </p> 
    * ${tags} 
    * ${see_to_overridden} 
    */

     

    代表方法 (Delegate Methods) 標簽:

    /** 
    * ${tags} 
    * ${see_to_target} 
    */ 


    getter
     方法標簽:

    /** 
    * @return ${bare_field_name} 
    */

    setter 方法標簽:

    /** 
    * @param ${param} 
    要設置的 ${bare_field_name} 
    */

    posted @ 2015-06-30 10:38 kelly 閱讀(255) | 評論 (0)編輯 收藏

    今天將寫好的附件服務器的API發(fā)給同事

     

    她引入我的jar后, 編譯就會報錯: 類文件具有錯誤的版本 50.0,應為 49.0

     

    50.0 對應的是JDK的1.6版本, 而49.0 對應的是JDK的1.5版本

     

    也就是說我的jar的版本高于她所用的版本

     

    由于我們實際部署在1.5之上, 所以我就來修改我的編譯環(huán)境

     

    首先我先修改了Eclipse的編譯環(huán)境到1.5, 但是沒有效果

     

    轉(zhuǎn)眼一想, 我都是使用Ant來打包發(fā)布, 看來Ant是自己編譯的

     

    于是我就在網(wǎng)上找到了修改Ant編譯版本的方法

     

     

     

    最后完成了修改

     

    寫個文字記錄下, 免得以后忘了= =

     

     

    PS: 我發(fā)現(xiàn)很多人問如何查看class文件是什么版本JDK編譯的, 現(xiàn)在我將方法寫在下面:

     

    使用UtralEdit打開一個class文件.

     

    根據(jù)java虛擬機的規(guī)范, java的class文件的前4個字節(jié)為magic number(魔數(shù)), 0xCAFEBABE(下圖的第一行0 - 3列), 標識這個文件是java的class文件

     

    而緊隨其后的4個字節(jié), 存儲的就是該class文件的主次版本號(下圖的第一行的 4 - 7 列), 下圖中的31 換算成十進制就是49, 這標識此class文件為JDK1.5編譯所得, 若32 就是JDK1.6編譯

     

    posted @ 2015-03-03 16:08 kelly 閱讀(441) | 評論 (0)編輯 收藏
    <mvc:annotation-driven />注解意義

    <mvc:annotation-driven /> 是一種簡寫形式,完全可以手動配置替代這種簡寫形式,簡寫形式可以讓初學都快速應用默認配置方案。<mvc:annotation-driven /> 會自動注冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,是spring MVC為@Controllers分發(fā)請求所必須的。
    并提供了:數(shù)據(jù)綁定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,讀寫XML的支持(JAXB),讀寫JSON的支持(Jackson)。
    后面,我們處理響應ajax請求時,就使用到了對json的支持。
    后面,對action寫JUnit單元測試時,要從spring IOC容器中取DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,來完成測試,取的時候要知道是<mvc:annotation-driven />這一句注冊的這兩個bean。

    posted @ 2014-11-16 22:42 kelly 閱讀(180) | 評論 (0)編輯 收藏
    1、確保導入了jackson-core-asl-1.9.13.jar和jackson-mapper-asl-1.9.13.jar包
    2、在spring的配置文件中加入<mvc:annotation-driven />這句,它提供了讀取jason的支持
    3、使用springMVC的@ResponseBody注解
    @responsebody表示該方法的返回結(jié)果直接寫入HTTP response body中
    一般在異步獲取數(shù)據(jù)時使用,在使用@RequestMapping后,返回值通常解析為跳轉(zhuǎn)路徑,加上@responsebody后返回結(jié)果不會被解析為跳轉(zhuǎn)路徑,而是直接寫入HTTP response body中。比如異步獲取json數(shù)據(jù),加上@responsebody后,會直接返回json數(shù)據(jù)。
    4、在以上配置都正確的情況下,我的項目還是不能返回json串。報錯:The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()。
    今天終于在一個外文網(wǎng)站找到答案,是由于spring版本的問題引起的。我之前一直用的是3.0.0的版本。就是因為這個版本的問題。于是果斷去官網(wǎng)下載3.2版本的,一切正常運行,成功返回json數(shù)據(jù)。
    posted @ 2014-11-16 22:41 kelly 閱讀(14149) | 評論 (1)編輯 收藏

    struts和spring整合首先要在Web容器啟動的時候自動裝配ApplicationContext的配置信息,可想而知應該在web.xml做相應的配置:
    [html]
    <context-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value> 
            classpath:applicationContext.xml 
        </param-value> 
    </context-param> 
    <listener> 
           <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
       </listener> 
    配置了org.springframework.web.context.ContextLoaderListener后我們就不惜要編寫代碼顯示地實例化ApplicationContext對象了。至于為什么要使用監(jiān)聽是因為web.xml 的加載順序是:context-param -> listener -> filter -> servlet 。如果你是在不想使用監(jiān)聽,或許你可以嘗試下繼承struts2的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter重寫這個它的init方法在StrutsPrepareAndExecuteFilter過濾器init中實例化ApplicationContext對象加載配置信息,雖然這種方法也可行,但是當攔截每個action都會加載一次配置信息,重新實例化了一個新的web容器,不僅浪費了資源也讓spring更加依賴了struts。

    1、使用xml方式:
    struts2配置
    <package name="user" extends="struts-default">
    <action name="login" class="userAction">
    <result name="success">/success.jsp</result>
    <result name="input" type="redirect">/index.jsp</result>
    </action>
    </package>
    spring配置
    <bean id="userDao" class="org.han.dao.impl.UserDaoImpl" />
    <bean id="biz" class="org.han.service.impl.LoginBizImpl">
    <property name="userdao" ref="userDao"/>
    </bean>

    <bean id="userAction" class="org.han.action.LoginAction" scope="prototype" >
    <property name="biz" ref="biz" />
    </bean>
    注意紅色部分,struts2的action class與對應的action bean必須相同,這樣才能由spring管理action;

    2、struts2使用零配置方式:
    當你導入了零配置插件包的時候千萬要注意約定大于配置,還是上面的spring配置,只是不需要struts2配置了。
    第一種方式:只需要將Action的className對應到spring配置中的bean id就行了
    @Action(value = "/login", results = { @Result(name = "success", location = "/success.jsp"),@Result(name="input",location="/index.jsp")},className="userAction")
    public String login() throws Exception {
    // TODO Auto-generated method stub
    User u=biz.login(this.getUser());
    if(u!=null){
    return SUCCESS;
    }
    return INPUT;
    }
    第二種方式:
    Action注解不需要className了,將spring配置稍作修改
    <bean id="org.han.action.LoginAction" class="org.han.action.LoginAction" scope="prototype" >
    <property name="biz" ref="biz" />
    </bean>
    這樣可以是因為當你使用零配置的時候,action的class默認是當前類的全類名,所以和spring整合的時候剛好使用全類名在spring配置中查找以全類名為id的bean。

    3、struts2、spring都使用注解方式:
    www.2cto.com
    <beans xmlns="http://www.springframework.org/schema/beans" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:context="http://www.springframework.org/schema/context" 
         xsi:schemaLocation="http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
             http://www.springframework.org/schema/context 
             http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
       <context:component-scan base-package="org.han.dao.impl,org.han.service.impl,org.han.action"/> 
    </beans> 

    <context:component-scan base-package=""/>用此種方式,不需要在配置文件中再配置bean,也不需要再導入上面對應的處理bean。也就是說可以不需要在配置文件中使用<context:annotation-config/>了,因為此種方式會自動導入

    [java]
    @Namespace("/") 
    @Component(value="userLogin") 
    @Scope(value="prototype") 
    public class LoginAction extends ActionSupport { 
     
        public LoginAction() { 
            super(); 
            // TODO Auto-generated constructor stub 
            System.out.println("action:"+this.hashCode()); 
        } 
         
        @Autowired 
        private ILoginBiz biz; 
        private User user; 
     
        public User getUser() { 
            return user; 
        } 
     
        public void setUser(User user) { 
            this.user = user; 
        } 
        @Autowired 
        public void setBiz(ILoginBiz biz) { 
            this.biz = biz; 
        } 
     
        @Override 
        @Action(value = "hello", results = { @Result(name = "success", location = "/success.jsp"),@Result(name="input",location="/index.jsp")}) 
        public String execute() throws Exception { 
            // TODO Auto-generated method stub 
            System.out.println("biz:"+this.biz.hashCode()); 
            User u=biz.login(this.getUser()); 
            if(u!=null){ 
                return SUCCESS; 
            } 
            return INPUT; 
        } 

    @Component 有一個可選的入?yún)ⅲ糜谥付?Bean 的名稱。一般情況下,Bean 都是 singleton 的,需要注入 Bean 的地方僅需要通過 byType 策略就可以自動注入了,所以大可不必指定 Bean 的名稱。除了提供 @Component 注釋外,還定義了幾個擁有特殊語義的注釋,它們分別是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,這 3 個注釋和 @Component 是等效的,但是從注釋類的命名上,很容易看出這 3 個注釋分別和持久層、業(yè)務層和控制層(Web 層)相對應。雖然目前這 3 個注釋和 @Component 相比沒有什么新意,但 Spring 將在以后的版本中為它們添加特殊的功能。所以,如果 Web 應用程序采用了經(jīng)典的三層分層結(jié)構(gòu)的話,最好在持久層、業(yè)務層和控制層分別采用 @Repository、@Service 和 @Controller 對分層中的類進行注釋,而用 @Component 對那些比較中立的類進行注釋。

    @Scope用于定義Bean的作用范圍。

    @Autowired 注釋,它可以對類成員變量、方法及構(gòu)造函數(shù)進行標注,完成自動裝配的工作。當 Spring 容器啟動時,AutowiredAnnotationBeanPostProcessor 將掃描 Spring 容器中所有 Bean,當發(fā)現(xiàn) Bean 中擁有 @Autowired 注釋時就找到和其匹配(默認按類型匹配)的 Bean,并注入到對應的地方中去。所以對成員變量使用 @Autowired 后,您大可將它們的 setter 方法刪除。

    @Qualifier(“name”) 中的 name是 Bean 的名稱,所以 @Autowired 和 @Qualifier 結(jié)合使用時,自動注入的策略就從 byType 轉(zhuǎn)變成 byName 了。@Autowired 可以對成員變量、方法以及構(gòu)造函數(shù)進行注釋,而 @Qualifier 的標注對象是成員變量、方法入?yún)ⅰ?gòu)造函數(shù)入?yún)ⅰ?/p>

    @PostConstruct 和 @PreDestroy:JSR-250 為初始化之后/銷毀之前方法的指定定義了兩個注釋類,這兩個注釋只能應用于方法上。標注了 @PostConstruct 注釋的方法將在類實例化后調(diào)用,而標注了 @PreDestroy 的方法將在類銷毀之前調(diào)用。
    通過 <bean> 元素的 init-method/destroy-method 屬性進行配置,都只能為 Bean 指定一個初始化 / 銷毀的方法。但是使用 @PostConstruct 和 @PreDestroy 注釋卻可以指定多個初始化 / 銷毀方法,那些被標注 @PostConstruct 或@PreDestroy 注釋的方法都會在初始化 / 銷毀時被執(zhí)行。
    更多的關(guān)于注解使用:請看官方文檔

    4、總結(jié):
    1、注釋配置不一定在先天上優(yōu)于 XML 配置。如果 Bean 的依賴關(guān)系是固定的,(如 Service 使用了哪幾個 DAO 類),這種配置信息不會在部署時發(fā)生調(diào)整,那么注釋配置優(yōu)于 XML 配置;反之如果這種依賴關(guān)系會在部署時發(fā)生調(diào)整,XML 配置顯然又優(yōu)于注釋配置,因為注釋是對 Java 源代碼的調(diào)整,您需要重新改寫源代碼并重新編譯才可以實施調(diào)整。
    2、如果 Bean 不是自己編寫的類(如 JdbcTemplate、SessionFactoryBean 等),注釋配置將無法實施,此時 XML 配置是唯一可用的方式。
    3、注釋配置往往是類級別的,而 XML 配置則可以表現(xiàn)得更加靈活。比如相比于 @Transaction 事務注釋,使用 aop/tx 命名空間的事務配置更加靈活和簡單。
    所以在實現(xiàn)應用中,我們往往需要同時使用注釋配置和 XML 配置,對于類級別且不會發(fā)生變動的配置可以優(yōu)先考慮注釋配置;而對于那些第三方類以及容易發(fā)生調(diào)整的配置則應優(yōu)先考慮使用 XML 配置。Spring 會在具體實施 Bean 創(chuàng)建和 Bean 注入之前將這兩種配置方式的元信息融合在一起。

    posted @ 2014-01-17 21:51 kelly 閱讀(290) | 評論 (0)編輯 收藏

    來自:http://hanyexiaoxiao.iteye.com/blog/410123
    1. 使用Spring注解來注入屬性 
    1.1. 使用注解以前我們是怎樣注入屬性的 
    類的實現(xiàn):

    public class UserManagerImpl implements UserManager {
    	private UserDao userDao;
    	public void setUserDao(UserDao userDao) {
    		this.userDao = userDao;
    	}
    	...
    }
    


    配置文件:

    <bean id="userManagerImpl" class="com.kedacom.spring.annotation.service.UserManagerImpl">
    	<property name="userDao" ref="userDao" />
    </bean>
    <bean id="userDao" class="com.kedacom.spring.annotation.persistence.UserDaoImpl">
    	<property name="sessionFactory" ref="mySessionFactory" />
    </bean>
    



    1.2. 引入@Autowired注解(不推薦使用,建議使用@Resource) 
    類的實現(xiàn)(對成員變量進行標注)

    public class UserManagerImpl implements UserManager {
    	@Autowired
    	private UserDao userDao;
    	...
    }
    


    或者(對方法進行標注)

    public class UserManagerImpl implements UserManager {
    	private UserDao userDao;
    	@Autowired
    	public void setUserDao(UserDao userDao) {
    		this.userDao = userDao;
    	}
    	...
    }
    


    配置文件

    <bean id="userManagerImpl" class="com.kedacom.spring.annotation.service.UserManagerImpl" />
    <bean id="userDao" class="com.kedacom.spring.annotation.persistence.UserDaoImpl">
    	<property name="sessionFactory" ref="mySessionFactory" />
    </bean>
    


    @Autowired可以對成員變量、方法和構(gòu)造函數(shù)進行標注,來完成自動裝配的工作。以上兩種不同實現(xiàn)方式中,@Autowired的標注位置不同,它們都會在Spring在初始化userManagerImpl這個bean時,自動裝配userDao這個屬性,區(qū)別是:第一種實現(xiàn)中,Spring會直接將UserDao類型的唯一一個bean賦值給userDao這個成員變量;第二種實現(xiàn)中,Spring會調(diào)用setUserDao方法來將UserDao類型的唯一一個bean裝配到userDao這個屬性。 

    1.3. 讓@Autowired工作起來 
    要使@Autowired能夠工作,還需要在配置文件中加入以下代碼

    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
    



    1.4. @Qualifier 
    @Autowired是根據(jù)類型進行自動裝配的。在上面的例子中,如果當Spring上下文中存在不止一個UserDao類型的bean時,就會拋出BeanCreationException異常;如果Spring上下文中不存在UserDao類型的bean,也會拋出BeanCreationException異常。我們可以使用@Qualifier配合@Autowired來解決這些問題。 
    1. 可能存在多個UserDao實例

    	@Autowired
    	public void setUserDao(@Qualifier("userDao") UserDao userDao) {
    		this.userDao = userDao;
    	}
    


    這樣,Spring會找到id為userDao的bean進行裝配。 
    2. 可能不存在UserDao實例

    	@Autowired(required = false)
    	public void setUserDao(UserDao userDao) {
    		this.userDao = userDao;
    	}
    



    1.5. @Resource(JSR-250標準注解,推薦使用它來代替Spring專有的@Autowired注解) 
    Spring 不但支持自己定義的@Autowired注解,還支持幾個由JSR-250規(guī)范定義的注解,它們分別是@Resource、@PostConstruct以及@PreDestroy。 
    @Resource的作用相當于@Autowired,只不過@Autowired按byType自動注入,而@Resource默認按byName自動注入罷了。@Resource有兩個屬性是比較重要的,分別是name和type,Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不指定name也不指定type屬性,這時將通過反射機制使用byName自動注入策略。 
    @Resource裝配順序

    1. 如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常
    2. 如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常
    3. 如果指定了type,則從上下文中找到類型匹配的唯一bean進行裝配,找不到或者找到多個,都會拋出異常
    4. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配(見2);如果沒有匹配,則回退為一個原始類型(UserDao)進行匹配,如果匹配則自動裝配;



    1.6. @PostConstruct(JSR-250) 
    在方法上加上注解@PostConstruct,這個方法就會在Bean初始化之后被Spring容器執(zhí)行(注:Bean初始化包括,實例化Bean,并裝配Bean的屬性(依賴注入))。 
    它的一個典型的應用場景是,當你需要往Bean里注入一個其父類中定義的屬性,而你又無法復寫父類的屬性或?qū)傩缘膕etter方法時,如:

    public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
    	private SessionFactory mySessionFacotry;
    	@Resource
    	public void setMySessionFacotry(SessionFactory sessionFacotry) {
    		this.mySessionFacotry = sessionFacotry;
    	}
    	@PostConstruct
    	public void injectSessionFactory() {
    		super.setSessionFactory(mySessionFacotry);
    	}
    	...
    }
    


    這里通過@PostConstruct,為UserDaoImpl的父類里定義的一個sessionFactory私有屬性,注入了我們自己定義的sessionFactory(父類的setSessionFactory方法為final,不可復寫),之后我們就可以通過調(diào)用super.getSessionFactory()來訪問該屬性了。 

    1.7. @PreDestroy(JSR-250) 
    在方法上加上注解@PreDestroy,這個方法就會在Bean初始化之后被Spring容器執(zhí)行。由于我們當前還沒有需要用到它的場景,這里不不去演示。其用法同@PostConstruct。 

    1.8. 使用<context:annotation-config />簡化配置 
    Spring2.1添加了一個新的context的Schema命名空間,該命名空間對注釋驅(qū)動、屬性文件引入、加載期織入等功能提供了便捷的配置。我們知道注釋本身是不會做任何事情的,它僅提供元數(shù)據(jù)信息。要使元數(shù)據(jù)信息真正起作用,必須讓負責處理這些元數(shù)據(jù)的處理器工作起來。 
    AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor就是處理這些注釋元數(shù)據(jù)的處理器。但是直接在Spring配置文件中定義這些Bean顯得比較笨拙。Spring為我們提供了一種方便的注冊這些BeanPostProcessor的方式,這就是<context:annotation-config />:

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    	http://www.springframework.org/schema/context
    	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    	<context:annotation-config />
    </beans>
    


    <context:annotationconfig />將隱式地向Spring容器注冊AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、 PersistenceAnnotationBeanPostProcessor以及RequiredAnnotationBeanPostProcessor這4個BeanPostProcessor。 

    2. 使用Spring注解完成Bean的定義 
    以上我們介紹了通過@Autowired或@Resource來實現(xiàn)在Bean中自動注入的功能,下面我們將介紹如何注解Bean,從而從XML配置文件中完全移除Bean定義的配置。 

    2.1. @Component(不推薦使用)、@Repository、@Service、@Controller 
    只需要在對應的類上加上一個@Component注解,就將該類定義為一個Bean了:

    @Component
    public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
    	...
    }
    


    使用@Component注解定義的Bean,默認的名稱(id)是小寫開頭的非限定類名。如這里定義的Bean名稱就是userDaoImpl。你也可以指定Bean的名稱: 
    @Component("userDao") 
    @Component是所有受Spring管理組件的通用形式,Spring還提供了更加細化的注解形式:@Repository、@Service、@Controller,它們分別對應存儲層Bean,業(yè)務層Bean,和展示層Bean。目前版本(2.5)中,這些注解與@Component的語義是一樣的,完全通用,在Spring以后的版本中可能會給它們追加更多的語義。所以,我們推薦使用@Repository、@Service、@Controller來替代@Component。 

    2.2. 使用<context:component-scan />讓Bean定義注解工作起來

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    	http://www.springframework.org/schema/context
    	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    	<context:component-scan base-package="com.kedacom.ksoa" />
    </beans>
    


    這里,所有通過<bean>元素定義Bean的配置內(nèi)容已經(jīng)被移除,僅需要添加一行<context:component-scan />配置就解決所有問題了——Spring XML配置文件得到了極致的簡化(當然配置元數(shù)據(jù)還是需要的,只不過以注釋形式存在罷了)。<context:component-scan />的base-package屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。 
    <context:component-scan />還允許定義過濾器將基包下的某些類納入或排除。Spring支持以下4種類型的過濾方式:

    • 過濾器類型 表達式范例 說明
    • 注解 org.example.SomeAnnotation 將所有使用SomeAnnotation注解的類過濾出來
    • 類名指定 org.example.SomeClass 過濾指定的類
    • 正則表達式 com\.kedacom\.spring\.annotation\.web\..* 通過正則表達式過濾一些類
    • AspectJ表達式 org.example..*Service+ 通過AspectJ表達式過濾一些類


    以正則表達式為例,我列舉一個應用實例:

    	<context:component-scan base-package="com.casheen.spring.annotation">
    		<context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
    	</context:component-scan>
    


    值得注意的是<context:component-scan />配置項不但啟用了對類包進行掃描以實施注釋驅(qū)動Bean定義的功能,同時還啟用了注釋驅(qū)動自動注入的功能(即還隱式地在內(nèi)部注冊了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此當使用<context:component-scan />后,就可以將<context:annotation-config />移除了。 

    2.3. 使用@Scope來定義Bean的作用范圍 
    在使用XML定義Bean時,我們可能還需要通過bean的scope屬性來定義一個Bean的作用范圍,我們同樣可以通過@Scope注解來完成這項工作:

    @Scope("session")
    @Component()
    public class UserSessionBean implements Serializable {
    	...
    }
    



    3. 參考 
    http://kingtai168.iteye.com/blog/244002 
    http://www.iteye.com/topic/244153 
    http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config 
    http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-classpath-scanning

    posted @ 2014-01-17 12:00 kelly 閱讀(257) | 評論 (0)編輯 收藏
         摘要: Struts2.3+Spring3.2的整合        這兩天都是一直在鼓搗Struts2.3如何整合Spring3.2以及dao層到底選用什么以及如何整合。下面就把自己這兩天的一些小成果分享出來也以便自己以后在實際項目中快速搭建。 首先是Struts2.3整合Spring3.2 1、新建一個web工程(這個就不說了) 2、添...  閱讀全文
    posted @ 2014-01-16 10:32 kelly 閱讀(1963) | 評論 (0)編輯 收藏

     警告信息如下:

    警告: No configuration found for the specified action: '/myNameSpace/login.action' in namespace: ''. Form action defaulting to 'action' attribute's literal value.

     

    struts.xml配置信息(部分)

     

    <package name="packageName" extends="struts-default" namespace="/myNameSpace">

        <action name="login" class="com.jato.srvclink.test.login.LoginAction" method="login">

     

    jsp頁面配置信息(部分)

     

    <s:form action="/myNameSpace/login.action">

     

    思考:沒有在''namespace中發(fā)現(xiàn)指定的action '/myNameSpace/login.action'

    答疑:因為配置的struts2標簽并未指定namespace屬性。所以struts2會默認從根命名空間"/"搜索action' /myNameSpace/login.action',如果搜索不到將進入默認命名空間''搜索action請求串,在默認命名空間中是肯定找不到我們 定義的action的,所以,struts2拋出一個警告信息。

    但是為什么我們沒有填寫namespace,我們的請求也可以正常訪問呢?

     

    我們來看一下解析后的html

    查看源碼得到的html(部分)

     

    <form id="login" onsubmit="return true;" action="/srvclink/myNameSpace/login.action" method="post">

     

    我們看到form提交的action串是準確的url請求,action串確實是/srvclin(應用根)/myNameSpace(命名空間)/login.action

    命名空間中找不到action定義,并不意味著這個action真的不存在,只是我們的代碼有問題而已。還有一點是我們在jsp頁面的action請求中 手動的加入了.action后綴。事實上struts2會自動追加.action的,因為我們并沒有合法的使用struts2的標簽,所以struts2 這里并沒有給我們追加.action,解析后的代碼中存在的.action,完全是我們手動在jsp頁面填寫的,有疑問的網(wǎng)友可以不手動添加查看 html

     

    我們修改我們的程序代碼

     

    jsp頁面配置信息(部分)修改后加入namespace屬性,修改action屬性值為/login.action

     

    <s:form action="/login.action" namespace="/myNameSpace">

     

    請求頁面后,大家很失望吧?警告依然存在。但是我們看一下警告信息。

     

    警告信息:

     

    警告: No configuration found for the specified action: '/login.action' in namespace: '/myNameSpace'. Form action defaulting to 'action' attribute's literal value.

     

    沒有在'/myNameSpace'namespace中發(fā)現(xiàn)指定的action '/login.action'

     

    毫無疑問,這里的警告和第一次的警告信息截然不同。我們現(xiàn)在存在命名空間,'/myNameSpace'能夠被struts2檢索到,并不是開始的''。那問題的關(guān)鍵在哪里呢?

    namespace中沒有發(fā)現(xiàn)指定的action '/login.action' ???

     

    我們來看一下struts.xml中的配置:

     

    struts.xml配置信息(部分)

     

    <package name="packageName" extends="struts-default" namespace="/myNameSpace">

        <action name="login" class="com.jato.srvclink.test.login.LoginAction" method="login">

     

    是的,我們'/myNameSpace'命名空間下,只有action名字為'login'的定義,并沒有所謂的'/login.action' 定義,所以struts2的警告并未錯。如果大家對這個抱有懷疑,可以修改action的名字'login'‘/longin.action’

    <action name="/login.action" class="com.jato.srvclink.test.login.LoginAction" method="login">

    請求頁面時你會發(fā)現(xiàn)不在報警告信息,原因很簡單。因為在命名空間為'myNameSpace'下確實存在命名為'/login.action'action

     

    我們再次修改配置文件

     

    jsp頁面配置信息(部分)修改后action屬性值為longin

     

    <s:form action="login" namespace="/myNameSpace">

     

    請求頁面時,我們發(fā)現(xiàn)不再有警告信息了。

     

    如果你有足夠細心,我想你應該可以徹底的明白為什么struts2會報警了吧?你也應該明白了使用struts2標簽action中添加/線后請求反而報錯的原因了。

    posted @ 2014-01-16 10:13 kelly 閱讀(257) | 評論 (0)編輯 收藏

      功能:本實例實現(xiàn)的功能是從輸入界面輸入用戶名和密碼,若用戶名和密碼正確轉(zhuǎn)到成功界面,否則轉(zhuǎn)到失敗界面。

       實現(xiàn):
       第一步:創(chuàng)建一個Web工程
       在MyEclipse,通過菜單File->New->Web Project,在Project Name輸入工程名稱Strut2Travel,點解確定完成創(chuàng)建一個工程。
       簡注:MyEclipse屬于一個IDE繼承開發(fā)環(huán)境,可以快速的創(chuàng)建Web項目。讀者可以手工創(chuàng)建,只需滿足項目的文件結(jié)構(gòu)即可。其中WEB-INF文件夾必不可少。

       第二步:導入Struts2的核心支持包
       commons-fileupload-1.2.1.jar

       commons-io-1.3.2.jar

       commons-logging-1.0.4.jar

       freemarker-2.3.15.jar

       ognl-2.7.3.jar

       struts2-core-2.1.8.1.jar

       xwork-core-2.1.6.jar
       簡注:Struts2有大量的jar包,支持大量的功能,不同類型的應用可能需要不同的包支持。以上的5個包為Struts2的核心包,使用Struts2必須使用。

       第三步:配置struts2轉(zhuǎn)發(fā)過濾器
       編輯web.xml文件,添加以下內(nèi)容
     <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
       org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
     </filter>
     <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
     </filter-mapping>
       簡注:“/*”表示涉及本工程的所有瀏覽器端的請求都經(jīng)過struts2過濾器處理。

        第四步:創(chuàng)建輸入頁面login.jsp、結(jié)果頁面welcome.jsp和error.jsp
    login.jsp
    <%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head><title>登錄界面</title></head>
      <body>
        <form action="LoginAction.action">
           用戶名:<input name="username"><br>
           密 碼:<input type="password" name="userpass"><br>
          <input type="submit" value="提 交">
          <input type="reset"  value="取 消">
        </form>
      </body>
    </html>


    welcome.jsp
    <%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>歡迎</title>
      </head>
      <body>
        <font color="red" size="10">登錄成功!</font>
      </body>
    </html>


    error.jsp
    <%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title></title>
      </head>
      <body>
        <font color="red" size="10">用戶或密碼錯誤!</font>
      </body>
    </html>
        簡注:本實例是最簡單的應用,以上為純JSP文件,Struts2提供大量使用的標簽,本書后面的實例會使用到。

        第五步:創(chuàng)建Action文件LoginAction和struts2.xml文件
    LoginAction.java
    package com;

    import com.opensymphony.xwork2.ActionSupport;

     

    public class LoginAction extends ActionSupport{
     private String username;
     private String userpass;
     
     public String execute(){
      if("daniel".equals(username)&&"abcde".equals(userpass))
       return SUCCESS;
      else
       return ERROR;
     }
     
     public String getUsername() {
      return username;
     }
     public void setUsername(String username) {
      this.username = username;
     }
     public String getUserpass() {
      return userpass;
     }
     public void setUserpass(String userpass) {
      this.userpass = userpass;
     }
    }


        簡注:默認配置情況下執(zhí)行execute()方法,實際應用中經(jīng)常更改配置。本書后面將深入講解。注意本類中的username和userpass必須和網(wǎng)頁文件的name屬性名一致。
    struts.xml
    <!DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
            "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
     <package name="struts2demo" extends="struts-default">
       <action name="loginAction" class="com.LoginAction">
         <result name="success">/welcome.jsp</result>
         <result name="error">/error.jsp</result>
       </action>
     </package>  
    </struts>

        第五步:將程序發(fā)布到Tomcat,啟動Tomcat即可。
        通過本實例讀者應該掌握如何配置并編寫一個最簡單最基本的應用,對于初學讀者以了解為主,沒必要深究一些問題。

    posted @ 2014-01-10 11:18 kelly 閱讀(278) | 評論 (0)編輯 收藏
         摘要: 使用注解來配置Action的最大好處就是可以實現(xiàn)零配置,但是事務都是有利有弊的,使用方便,維護起來就沒那么方便了。   要使用注解方式,我們必須添加一個額外包:struts2-convention-plugin-2.x.x.jar。   雖說是零配置的,但struts.xml還是少不了的,配置如下:   <?xml version="1.0" enc...  閱讀全文
    posted @ 2014-01-09 16:20 kelly 閱讀(202) | 評論 (0)編輯 收藏

     

    Struts2教程1:第一個Struts2程序

    在本系列教程中我們將學習到Struts2的各種技術(shù)。在本教程中使用的工具和程序庫的版本如下:

    開發(fā)工具:MyEclipse6

    Web服務器:Tomcat6

    Struts版本:Struts2.0.11.1

    JDK版本:JDK1.5.0_12

    J2EE版本:Java EE5.0

    在本系列教程中Web工程的上下文路徑都是struts2,如果在Web根目錄有一個index.jsp文件,則訪問路徑如下:

    http://localhost:8080/struts2/index.jsp

    由于MyEclipse6目前并不支持Struts2,所以我們需要到struts.apache.org去下載Struts2安裝包。要想正常使用Struts2,至少需要如下五個包(可能會因為Struts2的版本不同,包名略有差異,但包名的前半部是一樣的)。

    struts2-core-2.0.11.1.jar

    xwork-2.0.4.jar

    commons-logging-1.0.4.jar

    freemarker-2.3.8.jar

    ognl-2.6.11.jar

    Struts2雖然在大版本號上是第二個版本,但基本上在配置和使用上已經(jīng)完全顛覆了Struts1.x的方式(當然,Struts2仍然是基于MVC模式的,也是動作驅(qū)動的,可能這是唯一沒變的東西)。Struts2實際上是在Webwork基礎上構(gòu)建起來的MVC框架。我們從Struts2的源代碼中可以看到,有很多都是直接使用的xwork(Webwork的核心技術(shù))的包。既然從技術(shù)上來說Struts2是全新的框架,那么就讓我們來學習一下這個新的框架的使用方法。

    如果大家使用過Struts1.x,應該對建立基于Struts1.xWeb程序的基本步驟非常清楚。讓我們先來回顧一下建立基于Struts1.xWeb程序的基本步驟。

    1. 安裝Struts。由于Struts的入口點是ActionServlet,所以得在web.xml中配置一下這個Servlet

    2. 編寫Action類(一般從org.apache.struts.action.Action類繼承)。

    3. 編寫ActionForm類(一般從org.apache.struts.action.ActionForm類繼承),這一步不是必須的,如果要接收客戶端提交的數(shù)據(jù),需要執(zhí)行這一步。

    4. struts-config.xml文件中配置ActionActionForm

    5. 如果要采集用戶錄入的數(shù)據(jù),一般需要編寫若干JSP頁面,并通過這些JSP頁面中的form將數(shù)據(jù)提交給Action

    下面我們就按著編寫struts1.x程序的這五步和struts2.x程序的編寫過程一一對應,看看它們誰更“酷”。下面我們來編寫一個基于Struts2Web程序。這個程序的功能是讓用戶錄入兩個整數(shù),并提交給一個Struts Action,并計算這兩個數(shù)的代數(shù)和,如果代碼和為非負數(shù),則跳轉(zhuǎn)到positive.jsp頁面,否則跳轉(zhuǎn)到negative.jsp頁面。

    【第1步】 安裝Struts2

    這一步對于Struts1.xStruts2都是必須的,只是安裝的方法不同。Struts1的入口點是一個Servlet,而Struts2的入口點是一個過濾器(Filter)。因此,Struts2要按過濾器的方式配置。下面是在web.xml中配置Struts2的代碼:

    <filter>
    <filter-name>struts2</filter-name>
    <filter-class>
    org.apache.struts2.dispatcher.FilterDispatcher
    </filter-class>
    </filter>
    <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    【第2步】 編寫Action

    這一步和Struts1.x也必須進行。只是Struts1.x中的動作類必須從Action類中繼承,而Struts2.x的動作類需要從com.opensymphony.xwork2.ActionSupport類繼承。下面是計算兩個整數(shù)代碼和的Action類,代碼如下:
    package action;

    import com.opensymphony.xwork2.ActionSupport;

    public class FirstAction extends ActionSupport
    {
    private int operand1;
    private int operand2;

    public String execute() throws Exception
    {
    if (getSum() >= 0) // 如果代碼數(shù)和是非負整數(shù),跳到positive.jsp頁面
    {
    return "positive";
    }
    else // 如果代碼數(shù)和是負整數(shù),跳到negative.jsp頁面
    {
    return "negative";
    }
    }

    public int getOperand1()
    {
    return operand1;
    }

    public void setOperand1(int operand1)
    {
    System.out.println(operand1);
    this.operand1 = operand1;
    }

    public int getOperand2()
    {
    return operand2;
    }
    public void setOperand2(int operand2)
    {
    System.out.println(operand2);
    this.operand2 = operand2;
    }
    public int getSum()
    {
    return operand1 + operand2; // 計算兩個整數(shù)的代碼數(shù)和
    }
    }

    從上面的代碼可以看出,動作類的一個特征就是要覆蓋execute方法,只是Struts2execute方法沒有參數(shù)了,而Struts1.xexecute方法有四個參數(shù)。而且execute方法的返回值也不同的。Struts2只返回一個String,用于表述執(zhí)行結(jié)果(就是一個標志)。上面代碼的其他部分將在下面講解。

    【第3步】 編寫ActionForm

    在本例中當然需要使用ActionForm了。在Struts1.x中,必須要單獨建立一個ActionForm類(或是定義一個動作Form),而在Struts2ActionFormAction已經(jīng)二合一了。從第二步的代碼可以看出,后面的部分就是應該寫在ActionForm類中的內(nèi)容。所以在第2步,本例的ActionForm類已經(jīng)編寫完成(就是Action類的后半部分)。

    【第4步】 配置Action

    這一步struts1.xstruts2.x都是必須的,只是在struts1.x中的配置文件一般叫struts-config.xml(當然也可以是其他的文件名),而且一般放到WEB-INF目錄中。而在struts2.x中的配置文件一般為struts.xml,放到WEB-INF"classes目錄中。下面是在struts.xml中配置動作類的代碼:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
    >
    <struts>
    <package name="struts2" namespace="/mystruts"
    extends
    ="struts-default">
    <action name="sum" class="action.FirstAction">
    <result name="positive">/positive.jsp</result>
    <result name="negative">/negative.jsp</result>
    </action>
    </package>
    </struts>

    <struts>標簽中可以有多個<package>,第一個<package>可以指定一個Servlet訪問路徑(不包括動作名),如“/mystruts”。extends屬性繼承一個默認的配置文件“struts-default”,一般都繼承于它,大家可以先不去管它。<action>標簽中的name屬性表示動作名,class表示動作類名。

    <result>標簽的name實際上就是execute方法返回的字符串,如果返回的是“positive”,就跳轉(zhuǎn)到positive.jsp頁面,如果是“negative”,就跳轉(zhuǎn)到negative.jsp頁面。在<struts>中可以有多個<package>,在<package>中可以有多個<action>。我們可以用如下的URL來訪問這個動作:

    http://localhost:8080/struts2/mystruts/sum.action

    Struts1.x的動作一般都以.do結(jié)尾,而Struts2是以.action結(jié)尾。

    【第5步】 編寫用戶錄入接口(JSP頁面)

    1. 主界面(sum.jsp

    Web根目錄建立一個sum.jsp,代碼如下:

    <%@ page language="java" import="java.util.*" pageEncoding="GBK" %>
    <%@ taglib prefix="s" uri="/struts-tags"%>

    <html>
    <head>
    <title>輸入操作數(shù)</title>
    </head>

    <body>
    求代數(shù)和
    <br/>
    <s:form action="mystruts/sum.action" >
    <s:textfield name="operand1" label=" 操作數(shù)1"/>
    <s:textfield name="operand2" label=" 操作數(shù)2" />
    <s:submit value="代數(shù)和" />
    </s:form>
    </body>
    </html>

    sum.jsp中使用了Struts2帶的tag。在Struts2中已經(jīng)將Struts1.x的好幾個標簽庫都統(tǒng)一了,在Struts2中只有一個標簽庫/struts-tags。這里面包含了所有的Struts2標簽。但使用Struts2的標簽大家要注意一下。在<s:form>中最好都使用Struts2標簽,盡量不要用HTML或普通文本,大家可以將sum.jsp的代碼改為如下的形式,看看會出現(xiàn)什么效果:

    ... ...

    求代數(shù)和

    <br/>

    <s:form action="mystruts/sum.action" >

    操作數(shù)1<s:textfield name="operand1" /><br/>

    操作數(shù)2<s:textfield name="operand1" /><br/>

    <s:submit value="代數(shù)和" />

    </s:form>

    ... ...

    提示一下,在<s:form>Struts2使用<table>定位。

    2. positive.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
    <%@ taglib prefix="s" uri="/struts-tags" %>

    <html>
    <head>
    <title>顯示代數(shù)和</title>
    </head>

    <body>
    代數(shù)和為非負整數(shù)
    <h1><s:property value="sum" /></h1>
    </body>
    </html>

    3. negative.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
    <%@ taglib prefix="s" uri="/struts-tags" %>

    <html>
    <head>
    <title>顯示代數(shù)和</title>
    </head>

    <body>
    代數(shù)和為負整數(shù)
    <h1><s:property value="sum" /></h1>

    </body>
    </html>

    這兩個jsp頁面的實現(xiàn)代碼基本一樣,只使用了一個<s:property>標簽來顯示Action類中的sum屬性值。<s:property>標簽是從request對象中獲得了一個對象中得到的sum屬性,如我們可以使用如下的代碼來代替<s:property value=”sum”/>

     

    posted @ 2014-01-09 11:41 kelly 閱讀(200) | 評論 (0)編輯 收藏
         摘要:   Ibatis+spring整合集成開發(fā)   前面的文檔學習了ibatis的開發(fā),這節(jié)學習ibatis和spring的整合集成開發(fā)。 1.需要的開發(fā)包包括ibatis開發(fā)包和spring常用包     2.創(chuàng)建POJO實體類,Area.java和Define_industry.java package com.ibatis.samp...  閱讀全文
    posted @ 2014-01-09 11:38 kelly 閱讀(291) | 評論 (0)編輯 收藏

    理解ActionContext ValueStack Stack Context
    ActionContext
    一次Action調(diào)用都會創(chuàng)建一個ActionContext
    調(diào)用:ActionContext context = ActionContext.getContext()

    ValueStack
    OGNL框架實現(xiàn)
    可以把它簡單的看作一個棧(List

    Stack Object:放入stack中的對象,一般是action
    Stack Contextmap):stack上下文,它包含一系列對象,包括request/session/attr/application map等。
    EL:存取對象的任意屬性,調(diào)用對象的方法,遍歷整個對象結(jié)…

    ActionContextAction上下文,可以得到request session application
    ValueStack是值棧 存放表單中的值
    Stack Context 棧上下文 也是用來存值的



    struts2OGNL上下文的概念又做了進一步擴充,在struts2中,OGNL上下文通常如下所示:

    |--request 



    |--application 



    context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ] 



    |--session 



    |--attr 



    |--parameters




    Struts2中,采用標準命名的上下文(Context)來處理OGNL表達式。處理OGNL的頂級對象是一個Map(也叫context map),而OGNL在這個context中就是一個頂級對象(root)。在用法上,頂級對象的屬性訪問,是不需要任何標記前綴的。而其它非頂級的對象訪問,需要使用#標記。
    Struts2框架把OGNL Context設置為我們的ActionContext。并且ValueStack作為OGNL的根對象。除value stack之外,Struts2框架還把代表applicationsessionrequest這些對象的Map對象也放到ActionContext中去。(這也就是Struts2建議在Action類中不要直接訪問Servlet API的原因,他可以通過ActionContext對象來部分代替這些(Servlet API)功能,以方便對Action類進行測試!)
    Action的實例,總是放到value stack中。因為Action放在stack中,而stackroot(根對象),所以對Action中的屬性的訪問就可以省略#標記。但是,要訪問ActionContext中其它對象的屬性,就必須要帶上#標記,以便讓OGNL知道,不是從根對象,而是從其它對象中去尋找。
    那么訪問Action中的屬性的代碼就可以這樣寫

    <s:property value="postalCode"/>
    其它ActionContext中的非根對象屬性的訪問要像下面這樣寫:
    <s:property value="#session.mySessionPropKey"/> or
    <s:property value="#session['mySessionPropKey']"/> or
    <s:property value="#request['myRequestPropKey']"/>
    Collection的處理,內(nèi)容就很簡單。
    <s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
    這是處理List。這個代碼在頁面上建立一個下拉選項,內(nèi)容是list中的內(nèi)容,默認值是name2.
    處理map

    <s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />

    需要注意的是,判斷一個值是否在collection中。我們要使用in或者not in來處理。
    <s:if test="'foo' in {'foo','bar'}">
    muhahaha
    </s:if>
    <s:else>
    boo
    </s:else>
    另外,可以使用通配符來選擇collection對象的子集。
    ?——所有匹配選擇邏輯的元素
    ^——只提取符合選擇邏輯的第一個元素
    $——只提取符合選擇邏輯的最后一個元素
    person.relatives.{? #this.gender == 'male'}

    ?

    ?

    值棧(ValueStack) 
    Struts2OGNL上下文設置為Struts2中的ActionContext(內(nèi)部使用的仍然是OgnlContext),并將值棧設為OGNL的根對象。 
    我們知道,OGNL上下文中的根對象可以直接訪問,不需要使用任何特殊的“標記”,而引用上下文中的其他對象則需要使用“#”來標記。由于值棧是上下文中的根對象,因此可以直接訪問。那么對于值棧中的對象該如何訪問呢?Struts2提供了一個特殊的OGNLPropertyAccessor,它可以自動查找棧內(nèi)的所有對象(從棧頂?shù)綏5?/span>),直接找到一個具有你所查找的屬性的對象。也就是說,對于值棧中的任何對象都可以直接訪問,而不需要使用“#”。 
    假設值棧中有兩個對象:studentemployee,兩個對象都有name屬性,student有學號屬性number,而employee有薪水屬性salaryemployee先入棧,student后入棧,位于棧頂,那么對于表達式name,訪問的就是studentname屬性,因為student對象位于棧頂;表達式salary,訪問的就是employeesalary屬性。正如你所見,訪問值棧中的對象屬性或方法,無須指明對象,也不用“#”,就好像值棧中的對象都是OGNL上下文中的根對象一樣。這就是Struts2OGNL基礎上做出的改進。

     值棧中的Action實例 
    Struts2框架總是把Action實例放在棧頂。因為Action在值棧中,而值棧又是OGNL中的根,所以引用Action的屬性可以省略“#”標記,這也是為什么我們在結(jié)果頁面中可以直接訪問Action的屬性的原因。

     Struts2中的命名對象 
    Struts2還提供了一些命名對象,這些對象沒有保存在值棧中,而是保存在ActionContext中,因此訪問這些對象需要使用“#”標記。這些命名對象都是Map類型。 

    parameters 
    用于訪問請求參數(shù)。如:#parameters['id']#parameters.id,相當于調(diào)用了HttpServletRequest對象的getParameter()方法。 
    注意,parameters本質(zhì)上是一個使用HttpServletRequest對象中的請求參數(shù)構(gòu)造的Map對象,一量對象被創(chuàng)建(在調(diào)用Action實例之前就已經(jīng)創(chuàng)建好了),它和HttpServletRequest對象就沒有了任何關(guān)系。 

    request 
    用于訪問請求屬性。如:#request['user']#request.user,相當于調(diào)用了HttpServletRequest對象的getAttribute()方法。 

    session 
    用于訪問session屬性。如:#session['user']#session.user,相當于調(diào)用了HttpSession對象的getAttribute()方法。 

    application 
    用于訪問application屬性。如:#application['user']#application.user,相當于調(diào)用了ServletContextgetAttribute()方法。 

    attr 
    如果PageContext可用,則訪問PageContext,否則依次搜索requestsessionapplication對象。

    假設你的Action類中有變量String password; 要想獲取頁面中傳過來的password,必須為password設置get 和set 方法。當你的頁面進入Action時,ActionContext(Action上下文)通過set方法獲取password的值并壓入值棧棧頂,同時request也獲取到password的值,同時也如堆棧,session等對象的值也被壓入堆棧,ActionContext中的值在頁面中可以直接用<s:porperty value="password">取值顯示,而request中存儲的password通過<s:porperty value="#request.password">或者${password}取值。即struts是通過一個值棧來存儲所有對象和ActionContext中的值得。ActionContext為棧頂對象,也稱跟對象,ActionContext的值可以直接用變量名取,而其他的變量需要用#變量名取值。


    posted @ 2014-01-09 11:20 kelly 閱讀(477) | 評論 (0)編輯 收藏
    1. 一、什么是OGNL,有什么特點?   
    2.   
    3. OGNL(Object-Graph Navigation Language),大概可以理解為:對象圖形化導航語言。是一種可以方便地操作對象屬性的開源表達式語言。OGNL有如下特點:    
    4.   
    5. 1、支持對象方法調(diào)用,形式如:objName.methodName();   
    6.   
    7. 2、支持類靜態(tài)的方法調(diào)用和值訪問,表達式的格式為@[類全名(包括包路)]@[方法名  值名],例如:   
    8.   
    9. @java.lang.String@format('foo %s''bar')或@tutorial.MyConstant@APP_NAME;   
    10.   
    11. 3、支持賦值操作和表達式串聯(lián),例如:   
    12.   
    13. price=100discount=0.8calculatePrice(),這個表達式會返回80;   
    14.   
    15. 4、訪問OGNL上下文(OGNL context)和ActionContext;   
    16.   
    17. 5、操作集合對象。   
    18.   
    19.     
    20.   
    21. 二、使用OGNL表達式   
    22.   
    23. OGNL要結(jié)合struts標簽來使用。由于比較靈活,也容易把人給弄暈,尤其是“%”、“#”、“$”這三個符號的使用。由于$廣泛應用于EL中,這里重點寫%和#符號的用法。   
    24.   
    25. 1、“#”符號有三種用途:   
    26.   
    27. (1)、訪問非根對象(struts中值棧為根對象)如OGNL上下文和Action上下文,#相當于ActionContext.getContext();下表有幾個ActionContext中有用的屬性:   
    28.   
    29.     
    30.   
    31. 名稱   
    32.  作用   
    33.  例子   
    34.     
    35. parameters   
    36.  包含當前HTTP請求參數(shù)的Map   
    37.  #parameters.id[0]作用相當于request.getParameter("id"   
    38.     
    39. request   
    40.  包含當前HttpServletRequest的屬性(attribute)的Map   
    41.  #request.userName相當于request.getAttribute("userName"   
    42.     
    43. session   
    44.  包含當前HttpSession的屬性(attribute)的Map   
    45.  #session.userName相當于session.getAttribute("userName"   
    46.     
    47. application   
    48.  包含當前應用的ServletContext的屬性(attribute)的Map   
    49.  #application.userName相當于application.getAttribute("userName"   
    50.     
    51.   
    52. 注:attr 用于按request session application順序訪問其屬性(attribute),#attr.userName相當于按順序在以上三個范圍(scope)內(nèi)讀取userName屬性,直到找到為止。用于過濾和投影(projecting)集合,如books.{?#this.price<100};構(gòu)造Map,如#{'foo1':'bar1''foo2':'bar2'}。   
    53.   
    54.     
    55.   
    56. (2)、用于過濾和投影(projecting)集合,如: books.{?#this.price>35    
    57.   
    58. books.{?#this.price>35}   
    59.   
    60. (3)、構(gòu)造Map,如: #{'foo1':'bar1''foo2':'bar2'    
    61.   
    62. #{'foo1':'bar1''foo2':'bar2'}這種方式常用在給radio或select、checkbox等標簽賦值上。如果要在頁面中取一個map的值可以這樣寫:    
    63.   
    64. <s:property value="#myMap['foo1']"/>     
    65.   
    66. <s:property value="#myMap['foo1']"/>   
    67.   
    68. 2、“%”符號的用途是在標簽的屬性值被理解為字符串類型時,告訴執(zhí)行環(huán)境%{}里的是OGNL表達式。   
    69.   
    70. 這是一開始最讓我不能理解的符號,原因是一些相關(guān)資源在表述時不太準備,經(jīng)過一翻痛苦的探索,終于明白了它的用途。實際上就是讓被理解為字符串的表達式,被真正當成ognl來執(zhí)行。很有點類似javascript里面的eval_r()功能,例如 :   
    71.   
    72. var oDiv eval_r("document.all.div"+index)     
    73.   
    74. var oDiv eval_r("document.all.div"+index)   
    75.   
    76. 當index變量為1時,語句就會被當作var oDiv document.all.div1  var oDiv document.all.div1來執(zhí)行。%{}就是起這個作用。舉例:    
    77.   
    78. <s:set name="myMap" value="#{'key1':'value1','key2':'value2'}"/>      
    79.   
    80. <s:property value="#myMap['key1']"/>      
    81.   
    82. <s:url value="#myMap['key1']" />    
    83.   
    84. <s:set name="myMap" value="#{'key1':'value1','key2':'value2'}"/>   
    85.   
    86. <s:property value="#myMap['key1']"/>   
    87.   
    88. <s:url value="#myMap['key1']"/>   
    89.   
    90. 上面的代碼第2行會在頁面上輸出“value1”,而第3行則會輸出"#myMap['key1']"這么一個字符串。 如果將第3行改寫成這樣:    
    91.   
    92. <s:url value="%{#myMap['key1']}"/>     
    93.   
    94. <s:url value="%{#myMap['key1']}"/>   
    95.   
    96. 則輸出為“value1”。   
    97.   
    98.     
    99.   
    100.     
    101.   
    102. 這說明struts2里不同的標簽對ognl的表達式的理解是不一樣的。如果當有的標簽“看不懂”類似“#myMap['key1']”的語句時,就要用%{}來把這括進去,“翻譯”一下了。   
    103.   
    104. 3、“$”有兩種用途   
    105.   
    106. (1)、在國際化資源文件中,引用OGNL表達式。   
    107.   
    108. (2)、在Struts 2配置文件中,引用OGNL表達式:    
    109.   
    110. <action name="saveUser" class="userAction" method="save">   
    111.   
    112. <result type="redirect">listUser.action?msg=${msg}</result>   
    113.   
    114. </action>   
    115.   
    116. <action name="saveUser" class="userAction" method="save"      
    117.   
    118. <result type="redirect">listUser.action?msg=${msg}</result>   
    119.   
    120. </action>  

    posted @ 2014-01-08 13:58 kelly 閱讀(211) | 評論 (0)編輯 收藏
         摘要: Ibatis介紹與用例   一、介紹 ibatis 是一種“半自動化”的ORM實現(xiàn)。iBATIS是以SQL為中心的持久化層框架。能支持懶加載、關(guān)聯(lián)查詢、繼承等特性。iBATIS不同于一般的OR映射框架(eg:hibernate)。OR映射框架,將數(shù)據(jù)庫表、字段等映射到類、屬性,那是一種元數(shù)據(jù)(meta-data)映射。iBATIS則是將SQL查詢的參數(shù)和結(jié)果...  閱讀全文
    posted @ 2014-01-07 15:50 kelly 閱讀(371) | 評論 (0)編輯 收藏
         摘要: 深入Struts2的配置文件 本部分主要介紹struts.xml的常用配置。 1.1.    包配置: Struts2框架中核心組件就是Action、攔截器等,Struts2框架使用包來管理Action和攔截器等。每個包就是多個Action、多個攔截器、多個攔截器引用的集合。 在struts.xml文件中package元素用于定義包配置,每個pack...  閱讀全文
    posted @ 2014-01-07 15:39 kelly 閱讀(176) | 評論 (0)編輯 收藏
         摘要: 首頁要在web.xml中添加相應的struts配置: <servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servle...  閱讀全文
    posted @ 2013-12-27 14:56 kelly 閱讀(195) | 評論 (0)編輯 收藏

    1   編寫目的 

    本文詳細介紹了DBCP連接池的各個配置參數(shù)的含義,并通過實際例子演示不同的參數(shù)設置可能參數(shù)的結(jié)果。

    2   適用對象 

      項目實施人員

    3   參考資料 

    4   知識文件主要內(nèi)容4.1連接池知識簡介 

    總所周知建立數(shù)據(jù)庫連接是一個非常耗時耗資源的行為,因此現(xiàn)代的Web中間件,無論是開源的Tomcat、Jboss還是商業(yè)的websphere、weblogic都提供了數(shù)據(jù)庫連接池功能,可以毫不夸張的說,數(shù)據(jù)庫連接池性能的好壞,不同廠商對連接池有著不同的實現(xiàn),本文只介紹拜特公司使用較多的開源web中間件Tomcat中默認的連接池DBCP(DataBase connection pool)的使用。

    4.2Tomcat下配置連接池 

    下面以tomcat5.5.26為例來介紹如何配置連接池

    1:需要的jar

    在tomcat的安裝目錄common\lib下有一個naming-factory-dbcp.jar,這個是tomcat修改后的dbcp連接池實現(xiàn),同時為了能夠正常運行,還需要commons-pool.jar。

    2:建立context文件

    進入到conf\Catalina\localhost新建一個上下文文件,文件的名稱既為將來要訪問是輸入url上下文名稱,例如我們建立一個名為btweb的文件內(nèi)容如下:

    <Context debug="0" docBase="D:\v10_workspace\build\WebRoot"
    reloadable="false">
    <Resource
    name="jdbc/btdb1"
    type="javax.sql.DataSource"
    factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
    username="v10"
    password="v10"

    driverClassName="oracle.jdbc.driver.OracleDriver"

    url="jdbc:oracle:thin:@127.0.0.1:1521:cahs"
    maxActive="5"
    maxIdle="3"
    maxWait="5000"
    removeAbandoned="true"

    removeAbandonedTimeout="60"

    testOnBorrow="true"
    validationQuery="select count(*) from bt_user"
    logAbandoned="true"


    />
    </Context>

    4.3參數(shù)分步介紹 

    u
    數(shù)據(jù)庫連接相關(guān)

    username="v10"
    password="v10"

    driverClassName="oracle.jdbc.driver.OracleDriver"

    url="jdbc:oracle:thin:@127.0.0.1:1521:cahs"

    u
    jndi相關(guān)

    name="jdbc/btdb1"
    type="javax.sql.DataSource"
    factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

    factory默認是org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory,tomcat也允許采用其他連接實現(xiàn),不過默認使用dbcp。

    u
    連接數(shù)控制與連接歸還策略
    maxActive="5"

    maxIdle="3"

    minIdle=”2”
    maxWait="5000"

    u
      應對網(wǎng)絡不穩(wěn)定的策略

    testOnBorrow="true"
    validationQuery="select count(*) from bt_user"

    u
    應對連接泄漏的策略
    removeAbandoned="true"

    removeAbandonedTimeout="60"


    logAbandoned="true"

       

    如下圖所示:連接池處于應用程序與數(shù)據(jù)庫之間,一方面應用程序通過它來獲取連接,歸還連接,另一方面連接又需要從數(shù)據(jù)里獲取連接,歸還連接。

    步驟1:系統(tǒng)啟動

    系統(tǒng)啟動時,初始化連接池,由于沒有任何請求連接池中連接數(shù)為0。

    maxActive="5"

    表示并發(fā)情況下最大可從連接池中獲取的連接數(shù)。如果數(shù)據(jù)庫不是單獨,供一個應用使用,通過設置maxActive參數(shù)可以避免某個應用無限制的獲取連接對其他應用造成影響,如果一個數(shù)據(jù)庫只是用來支持一個應用那么maxActive理論上可以設置成該數(shù)據(jù)庫可以支撐的最大連接數(shù)。maxActive只是表示通過連接池可以并發(fā)的獲取的最大連接數(shù)。

    從圖上我們可以看到連接的獲取與釋放是雙向,當應用程序并發(fā)請求連接池時,連接池就需要從數(shù)據(jù)庫獲取連接,那么但應用程序使用完連接并將連接歸還給連接池時,連接池是否也同時將連接歸還給數(shù)據(jù)庫呢?很顯然答案是否定的,如果那樣的話連接池就變得多此一舉,不但不能提高性能,反而會降低性能,那么但應用成歸還連接后,連接池如何處理呢?

    maxIdle="3"

    如果在并發(fā)時達到了maxActive=5,那么連接池就必須從數(shù)據(jù)庫中獲取5個連接來供應用程序使用,當應用程序關(guān)閉連接后,由于maxIdle=3,因此并不是所有的連接都會歸還給數(shù)據(jù)庫,將會有3個連接保持在連接池種中,狀態(tài)為空閑。

    minIdle=2

    最小默認情況下并不生效,它的含義是當連接池中的連接少有minIdle,系統(tǒng)監(jiān)控線程將啟動補充功能,一般情況下我們并不啟動補充線程。

    問題:如何設置maxActive和maxIdle?

    理論上講maxActive應該設置成應用的最大并發(fā)數(shù),這樣一來即便是在最大并發(fā)的情況下,應用依然能夠從連接池中獲取連接,但是困難時的是我們很難準確估計到最大并發(fā)數(shù),設置成最大并發(fā)數(shù)是一種最優(yōu)的服務質(zhì)量保證,事實上,如果某個用戶登錄提示系統(tǒng)繁忙,那么在他再次登錄時,可能系統(tǒng)資源已經(jīng)充足,對于拜特資金管理系統(tǒng)我們建議將maxActive設置為系統(tǒng)注冊人數(shù)的十分之一到二十分之一之間。例如系統(tǒng)的注冊人數(shù)為1000,那么設置成50-100靠近100的數(shù)字,例如85或90。


    maxIdle對應的連接,實際上是連接池保持的長連接,這也是連接池發(fā)揮優(yōu)勢的部分,理論上講保持較多的長連接,在應用請求時可以更快的響應,但是過多的連接保持,反而會消耗數(shù)據(jù)庫大量的資源,因此maxIdle也并不是越大越好,同上例我們建議將maxIdle設置成

    50-100中靠近50的數(shù)字,例如55。這樣就能在兼顧最大并發(fā)同時,保持較少的數(shù)據(jù)庫連接,而且在絕大多情況,能夠為應用程序提供最快的相應速度。

    testOnBorrow="true"

    validationQuery="select count(*) from bt_user"

    我們知道數(shù)據(jù)庫連接從本質(zhì)上架構(gòu)在tcp/ip連接之上,一般情況下web服務器與數(shù)據(jù)庫服務器都不在同一臺物理機器上,而是通過網(wǎng)絡進行連接,那么當建立數(shù)據(jù)庫連接池的機器與數(shù)據(jù)庫服務器自己出現(xiàn)網(wǎng)絡異常時,保持在連接池中的連接將失效,不能夠在次使用,傳統(tǒng)的情況下只能通過重新啟動,再次建立連接,通過設置以上兩個參數(shù),但應用程序從連接池中獲取連接時,會首先進行活動性檢測,當獲取的連接是活動的時候才會給應用程序使用,如果連接失效,連接將釋放該連接。validationQuery是一條測試語句,沒有實際意義,現(xiàn)實中,一般用一條最為簡單的查詢語句充當。

    removeAbandoned="true"

    removeAbandonedTimeout="60"

    logAbandoned="true"

    有時粗心的程序編寫者在從連接池中獲取連接使用后忘記了連接的關(guān)閉,這樣連池的連接就會逐漸達到maxActive直至連接池無法提供服務。現(xiàn)代連接池一般提供一種“智能”的檢查,但設置了removeAbandoned="true"時,當連接池連接數(shù)到達(getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)時便會啟動連接回收,那種活動時間超過removeAbandonedTimeout="60"的連接將會被回收,同時如果logAbandoned="true"設置為true,程序在回收連接的同時會打印日志。removeAbandoned是連接池的高級功能,理論上這中配置不應該出現(xiàn)在實際的生產(chǎn)環(huán)境,因為有時應用程序執(zhí)行長事務,可能這種情況下,會被連接池誤回收,該種配置一般在程序測試階段,為了定位連接泄漏的具體代碼位置,被開啟,生產(chǎn)環(huán)境中連接的關(guān)閉應該靠程序自己保證。

    posted @ 2013-12-20 23:01 kelly 閱讀(1529) | 評論 (0)編輯 收藏

    一般情況下,URL 中的參數(shù)應使用 url 編碼規(guī)則,即把參數(shù)字符串中除了 -_. 之外的所有非字母數(shù)字字符都將被替換成百分號(%)后跟兩位十六進制數(shù),空格則編碼為加號(+)。但是對于帶有中文的參數(shù)來說,這種編碼會使編碼后的字符串變得很長。如果希望有短一點的方式對參數(shù)編碼,可以采用 base64 編碼方式對字符串進行編碼,但是 base64 編碼方式不能處理 JavaScript 中的中文,因為 JavaScript 中的中文都是以 UTF-16 方式保存的。而 base64 只能處理單字節(jié)字符,所以不能直接用 base64 對帶有中文的 JavaScript 字符串進行編碼。但是可以通過 utf.js 這個程序中提供的 utf16to8 來將 UTF-16 編碼的中文先轉(zhuǎn)化為 UTF-8 方式,然后再進行 base64 編碼。這樣編碼后的字符串,在傳遞到服務器端后可以直接通過 base64_decode 解碼成 UTF-8 的中文字符串。但是還有個問題需要注意。base64 編碼中使用了加號(+),而 + 在 URL 傳遞時會被當成空格,因此必須要將 base64 編碼后的字符串中的加號替換成 %2B 才能當作 URL 參數(shù)進行傳遞。否則在服務器端解碼后就會出錯。

    所以我們需要做的就是:
    js中:encodeURI(str).replace(/\+/g,'%2B')
    java中:str.replaceAll("\\+","%2B")

    posted @ 2013-12-17 11:03 kelly 閱讀(1542) | 評論 (0)編輯 收藏
    主站蜘蛛池模板: 亚洲天堂中文字幕| 亚洲av无码av在线播放| 啦啦啦高清视频在线观看免费| 亚洲第一街区偷拍街拍| 亚洲午夜理论片在线观看| 国产一级片免费看| 亚洲黄色在线网站| 国产精品成人免费综合| 黄色网站软件app在线观看免费| 亚洲日韩涩涩成人午夜私人影院| 中国国产高清免费av片| 亚洲国产乱码最新视频| 亚洲中文字幕无码日韩| 成年女人男人免费视频播放| 中文字幕视频在线免费观看| 国产亚洲精品一品区99热| 久久久久久国产a免费观看黄色大片| 一本岛v免费不卡一二三区| 亚洲免费黄色网址| 亚洲中文字幕在线观看| 成人免费视频试看120秒| 久久精品无码精品免费专区| 国产亚洲综合视频| 亚洲国产高清视频在线观看| 亚洲日韩精品无码一区二区三区| 中国在线观看免费国语版| 九九美女网站免费| 男男gay做爽爽免费视频| 亚洲人成网站18禁止久久影院| 国产亚洲精品a在线无码| 国产小视频在线观看免费| 8888四色奇米在线观看免费看| 国产精品美女免费视频观看| 亚洲成熟丰满熟妇高潮XXXXX| 亚洲激情视频网站| 亚洲欧洲免费视频| 亚洲情XO亚洲色XO无码| 亚洲国产成人久久综合一区77 | 一二三四在线播放免费观看中文版视频 | 97久久精品亚洲中文字幕无码 | 亚洲人成自拍网站在线观看|