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

          常用鏈接

          留言簿(4)

          隨筆分類(66)

          隨筆檔案(72)

          文章檔案(19)

          收藏夾

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

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

          但在使用時(shí)要注意一下幾點(diǎn):

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

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

          在Spring-common.xml中只對(duì)一些事務(wù)邏輯的注解掃描。

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

          com.fq.controlller

          com.fq.service

          就先給定這兩個(gè)包機(jī)構(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>

          可以看出要把最終的包寫(xiě)上,而不能這樣寫(xiě)base-package=”com.fq”。這種寫(xiě)法對(duì)于include-filter來(lái)講它都會(huì)掃描,而不是僅僅掃描@Controller。哈哈哈,這點(diǎn)需要注意。他一般會(huì)導(dǎo)致一個(gè)常見(jiàn)的錯(cuò)誤,那就是事務(wù)不起作用,補(bǔ)救的方法是添加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。對(duì)于exculude-filter不存在包不精確后都進(jìn)行掃描的問(wèn)題。

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


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

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

          -Dosgi.requiredJavaVersion=1.5(可選)

          -Xms512m

          -Xmx1024m

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

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

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

          myeclipse自定義java注釋:

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

          然后展開(kāi)Comments節(jié)點(diǎn)就是所有需設(shè)置注釋的元素

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

          文件 (Files) 注釋標(biāo)簽:

          /** 

          @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) 注釋標(biāo)簽(類的注釋):

          /**

            * @ClassName ${type_name}

            * @Description ${todo}

            * @author shenyanghong ahong2011@gmail.com

            * @date ${date}

            * ${tags}

          */

          字段 (Fields) 注釋標(biāo)簽:

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


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

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

           

          方法 (Constructor & Methods) 標(biāo)簽:

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

          覆蓋方法 (Overriding Methods) 標(biāo)簽:

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

           

          代表方法 (Delegate Methods) 標(biāo)簽:

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


          getter
           方法標(biāo)簽:

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

          setter 方法標(biāo)簽:

          /** 
          * @param ${param} 
          要設(shè)置的 ${bare_field_name} 
          */

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

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

           

          她引入我的jar后, 編譯就會(huì)報(bào)錯(cuò): 類文件具有錯(cuò)誤的版本 50.0,應(yīng)為 49.0

           

          50.0 對(duì)應(yīng)的是JDK的1.6版本, 而49.0 對(duì)應(yīng)的是JDK的1.5版本

           

          也就是說(shuō)我的jar的版本高于她所用的版本

           

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

           

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

           

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

           

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

           

           

           

          最后完成了修改

           

          寫(xiě)個(gè)文字記錄下, 免得以后忘了= =

           

           

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

           

          使用UtralEdit打開(kāi)一個(gè)class文件.

           

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

           

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

           

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

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

          posted @ 2014-11-16 22:42 kelly 閱讀(179) | 評(píng)論 (0)編輯 收藏
          1、確保導(dǎo)入了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é)果直接寫(xiě)入HTTP response body中
          一般在異步獲取數(shù)據(jù)時(shí)使用,在使用@RequestMapping后,返回值通常解析為跳轉(zhuǎn)路徑,加上@responsebody后返回結(jié)果不會(huì)被解析為跳轉(zhuǎn)路徑,而是直接寫(xiě)入HTTP response body中。比如異步獲取json數(shù)據(jù),加上@responsebody后,會(huì)直接返回json數(shù)據(jù)。
          4、在以上配置都正確的情況下,我的項(xiàng)目還是不能返回json串。報(bào)錯(cuò):The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()。
          今天終于在一個(gè)外文網(wǎng)站找到答案,是由于spring版本的問(wèn)題引起的。我之前一直用的是3.0.0的版本。就是因?yàn)檫@個(gè)版本的問(wèn)題。于是果斷去官網(wǎng)下載3.2版本的,一切正常運(yùn)行,成功返回json數(shù)據(jù)。
          posted @ 2014-11-16 22:41 kelly 閱讀(14147) | 評(píng)論 (1)編輯 收藏

          struts和spring整合首先要在Web容器啟動(dòng)的時(shí)候自動(dòng)裝配ApplicationContext的配置信息,可想而知應(yīng)該在web.xml做相應(yīng)的配置:
          [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后我們就不惜要編寫(xiě)代碼顯示地實(shí)例化ApplicationContext對(duì)象了。至于為什么要使用監(jiān)聽(tīng)是因?yàn)閣eb.xml 的加載順序是:context-param -> listener -> filter -> servlet 。如果你是在不想使用監(jiān)聽(tīng),或許你可以嘗試下繼承struts2的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter重寫(xiě)這個(gè)它的init方法在StrutsPrepareAndExecuteFilter過(guò)濾器init中實(shí)例化ApplicationContext對(duì)象加載配置信息,雖然這種方法也可行,但是當(dāng)攔截每個(gè)action都會(huì)加載一次配置信息,重新實(shí)例化了一個(gè)新的web容器,不僅浪費(fèi)了資源也讓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與對(duì)應(yīng)的action bean必須相同,這樣才能由spring管理action;

          2、struts2使用零配置方式:
          當(dāng)你導(dǎo)入了零配置插件包的時(shí)候千萬(wàn)要注意約定大于配置,還是上面的spring配置,只是不需要struts2配置了。
          第一種方式:只需要將Action的className對(duì)應(yīng)到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>
          這樣可以是因?yàn)楫?dāng)你使用零配置的時(shí)候,action的class默認(rèn)是當(dāng)前類的全類名,所以和spring整合的時(shí)候剛好使用全類名在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,也不需要再導(dǎo)入上面對(duì)應(yīng)的處理bean。也就是說(shuō)可以不需要在配置文件中使用<context:annotation-config/>了,因?yàn)榇朔N方式會(huì)自動(dòng)導(dǎo)入

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

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

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

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

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

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

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

          來(lái)自:http://hanyexiaoxiao.iteye.com/blog/410123
          1. 使用Spring注解來(lái)注入屬性 
          1.1. 使用注解以前我們是怎樣注入屬性的 
          類的實(shí)現(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) 
          類的實(shí)現(xiàn)(對(duì)成員變量進(jìn)行標(biāo)注)

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


          或者(對(duì)方法進(jìn)行標(biāo)注)

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

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

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



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

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


          這樣,Spring會(huì)找到id為userDao的bean進(jìn)行裝配。 
          2. 可能不存在UserDao實(shí)例

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



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

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



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

          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);
          	}
          	...
          }
          


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

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

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

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

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

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


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

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

          <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>
          


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

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


          以正則表達(dá)式為例,我列舉一個(gè)應(yīng)用實(shí)例:

          	<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 />配置項(xiàng)不但啟用了對(duì)類包進(jìn)行掃描以實(shí)施注釋驅(qū)動(dòng)Bean定義的功能,同時(shí)還啟用了注釋驅(qū)動(dòng)自動(dòng)注入的功能(即還隱式地在內(nèi)部注冊(cè)了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此當(dāng)使用<context:component-scan />后,就可以將<context:annotation-config />移除了。 

          2.3. 使用@Scope來(lái)定義Bean的作用范圍 
          在使用XML定義Bean時(shí),我們可能還需要通過(guò)bean的scope屬性來(lái)定義一個(gè)Bean的作用范圍,我們同樣可以通過(guò)@Scope注解來(lái)完成這項(xiàng)工作:

          @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 閱讀(255) | 評(píng)論 (0)編輯 收藏
               摘要: Struts2.3+Spring3.2的整合        這兩天都是一直在鼓搗Struts2.3如何整合Spring3.2以及dao層到底選用什么以及如何整合。下面就把自己這兩天的一些小成果分享出來(lái)也以便自己以后在實(shí)際項(xiàng)目中快速搭建。 首先是Struts2.3整合Spring3.2 1、新建一個(gè)web工程(這個(gè)就不說(shuō)了) 2、添...  閱讀全文
          posted @ 2014-01-16 10:32 kelly 閱讀(1963) | 評(píng)論 (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頁(yè)面配置信息(部分)

           

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

           

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

          答疑:因?yàn)榕渲玫?/span>struts2標(biāo)簽并未指定namespace屬性。所以struts2會(huì)默認(rèn)從根命名空間"/"搜索action' /myNameSpace/login.action',如果搜索不到將進(jìn)入默認(rèn)命名空間''搜索action請(qǐng)求串,在默認(rèn)命名空間中是肯定找不到我們 定義的action的,所以,struts2拋出一個(gè)警告信息。

          但是為什么我們沒(méi)有填寫(xiě)namespace,我們的請(qǐng)求也可以正常訪問(wèn)呢?

           

          我們來(lái)看一下解析后的html

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

           

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

           

          我們看到form提交的action串是準(zhǔn)確的url請(qǐng)求,action串確實(shí)是/srvclin(應(yīng)用根)/myNameSpace(命名空間)/login.action。

          命名空間中找不到action定義,并不意味著這個(gè)action真的不存在,只是我們的代碼有問(wèn)題而已。還有一點(diǎn)是我們?cè)?/span>jsp頁(yè)面的action請(qǐng)求中 手動(dòng)的加入了.action后綴。事實(shí)上struts2會(huì)自動(dòng)追加.action的,因?yàn)槲覀儾](méi)有合法的使用struts2的標(biāo)簽,所以struts2 這里并沒(méi)有給我們追加.action,解析后的代碼中存在的.action,完全是我們手動(dòng)在jsp頁(yè)面填寫(xiě)的,有疑問(wèn)的網(wǎng)友可以不手動(dòng)添加查看 html

           

          我們修改我們的程序代碼

           

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

           

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

           

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

           

          警告信息:

           

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

           

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

           

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

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

           

          我們來(lái)看一下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'的定義,并沒(méi)有所謂的'/login.action' 定義,所以struts2的警告并未錯(cuò)。如果大家對(duì)這個(gè)抱有懷疑,可以修改action的名字'login'‘/longin.action’

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

          請(qǐng)求頁(yè)面時(shí)你會(huì)發(fā)現(xiàn)不在報(bào)警告信息,原因很簡(jiǎn)單。因?yàn)樵诿臻g為'myNameSpace'下確實(shí)存在命名為'/login.action'action。

           

          我們?cè)俅涡薷呐渲梦募?/span>

           

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

           

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

           

          請(qǐng)求頁(yè)面時(shí),我們發(fā)現(xiàn)不再有警告信息了。

           

          如果你有足夠細(xì)心,我想你應(yīng)該可以徹底的明白為什么struts2會(huì)報(bào)警了吧?你也應(yīng)該明白了使用struts2標(biāo)簽action中添加/線后請(qǐng)求反而報(bào)錯(cuò)的原因了。

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

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

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

             第二步:導(dǎo)入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
             簡(jiǎn)注:Struts2有大量的jar包,支持大量的功能,不同類型的應(yīng)用可能需要不同的包支持。以上的5個(gè)包為Struts2的核心包,使用Struts2必須使用。

             第三步:配置struts2轉(zhuǎn)發(fā)過(guò)濾器
             編輯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>
             簡(jiǎn)注:“/*”表示涉及本工程的所有瀏覽器端的請(qǐng)求都經(jīng)過(guò)struts2過(guò)濾器處理。

              第四步:創(chuàng)建輸入頁(yè)面login.jsp、結(jié)果頁(yè)面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">用戶或密碼錯(cuò)誤!</font>
            </body>
          </html>
              簡(jiǎn)注:本實(shí)例是最簡(jiǎn)單的應(yīng)用,以上為純JSP文件,Struts2提供大量使用的標(biāo)簽,本書(shū)后面的實(shí)例會(huì)使用到。

              第五步:創(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;
           }
          }


              簡(jiǎn)注:默認(rèn)配置情況下執(zhí)行execute()方法,實(shí)際應(yīng)用中經(jīng)常更改配置。本書(shū)后面將深入講解。注意本類中的username和userpass必須和網(wǎng)頁(yè)文件的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,啟動(dòng)Tomcat即可。
              通過(guò)本實(shí)例讀者應(yīng)該掌握如何配置并編寫(xiě)一個(gè)最簡(jiǎn)單最基本的應(yīng)用,對(duì)于初學(xué)讀者以了解為主,沒(méi)必要深究一些問(wèn)題。

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

           

          Struts2教程1:第一個(gè)Struts2程序

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

          開(kāi)發(fā)工具:MyEclipse6

          Web服務(wù)器:Tomcat6

          Struts版本:Struts2.0.11.1

          JDK版本:JDK1.5.0_12

          J2EE版本:Java EE5.0

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

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

          由于MyEclipse6目前并不支持Struts2,所以我們需要到struts.apache.org去下載Struts2安裝包。要想正常使用Struts2,至少需要如下五個(gè)包(可能會(huì)因?yàn)?/span>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雖然在大版本號(hào)上是第二個(gè)版本,但基本上在配置和使用上已經(jīng)完全顛覆了Struts1.x的方式(當(dāng)然,Struts2仍然是基于MVC模式的,也是動(dòng)作驅(qū)動(dòng)的,可能這是唯一沒(méi)變的東西)。Struts2實(shí)際上是在Webwork基礎(chǔ)上構(gòu)建起來(lái)的MVC框架。我們從Struts2的源代碼中可以看到,有很多都是直接使用的xwork(Webwork的核心技術(shù))的包。既然從技術(shù)上來(lái)說(shuō)Struts2是全新的框架,那么就讓我們來(lái)學(xué)習(xí)一下這個(gè)新的框架的使用方法。

          如果大家使用過(guò)Struts1.x,應(yīng)該對(duì)建立基于Struts1.xWeb程序的基本步驟非常清楚。讓我們先來(lái)回顧一下建立基于Struts1.xWeb程序的基本步驟。

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

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

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

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

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

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

          【第1步】 安裝Struts2

          這一步對(duì)于Struts1.xStruts2都是必須的,只是安裝的方法不同。Struts1的入口點(diǎn)是一個(gè)Servlet,而Struts2的入口點(diǎn)是一個(gè)過(guò)濾器(Filter)。因此,Struts2要按過(guò)濾器的方式配置。下面是在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步】 編寫(xiě)Action

          這一步和Struts1.x也必須進(jìn)行。只是Struts1.x中的動(dòng)作類必須從Action類中繼承,而Struts2.x的動(dòng)作類需要從com.opensymphony.xwork2.ActionSupport類繼承。下面是計(jì)算兩個(gè)整數(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ù)和是非負(fù)整數(shù),跳到positive.jsp頁(yè)面
          {
          return "positive";
          }
          else // 如果代碼數(shù)和是負(fù)整數(shù),跳到negative.jsp頁(yè)面
          {
          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; // 計(jì)算兩個(gè)整數(shù)的代碼數(shù)和
          }
          }

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

          【第3步】 編寫(xiě)ActionForm

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

          【第4步】 配置Action

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

          <?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>標(biāo)簽中可以有多個(gè)<package>,第一個(gè)<package>可以指定一個(gè)Servlet訪問(wèn)路徑(不包括動(dòng)作名),如“/mystruts”。extends屬性繼承一個(gè)默認(rèn)的配置文件“struts-default”,一般都繼承于它,大家可以先不去管它。<action>標(biāo)簽中的name屬性表示動(dòng)作名,class表示動(dòng)作類名。

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

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

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

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

          1. 主界面(sum.jsp

          Web根目錄建立一個(gè)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的好幾個(gè)標(biāo)簽庫(kù)都統(tǒng)一了,在Struts2中只有一個(gè)標(biāo)簽庫(kù)/struts-tags。這里面包含了所有的Struts2標(biāo)簽。但使用Struts2的標(biāo)簽大家要注意一下。在<s:form>中最好都使用Struts2標(biāo)簽,盡量不要用HTML或普通文本,大家可以將sum.jsp的代碼改為如下的形式,看看會(huì)出現(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ù)和為非負(fù)整數(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ù)和為負(fù)整數(shù)
          <h1><s:property value="sum" /></h1>

          </body>
          </html>

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

           

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

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

          ValueStack
          OGNL框架實(shí)現(xiàn)
          可以把它簡(jiǎn)單的看作一個(gè)棧(List 。

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

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



          struts2對(duì)OGNL上下文的概念又做了進(jìn)一步擴(kuò)充,在struts2中,OGNL上下文通常如下所示:

          |--request 



          |--application 



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



          |--session 



          |--attr 



          |--parameters




          Struts2中,采用標(biāo)準(zhǔn)命名的上下文(Context)來(lái)處理OGNL表達(dá)式。處理OGNL的頂級(jí)對(duì)象是一個(gè)Map(也叫context map),而OGNL在這個(gè)context中就是一個(gè)頂級(jí)對(duì)象(root)。在用法上,頂級(jí)對(duì)象的屬性訪問(wèn),是不需要任何標(biāo)記前綴的。而其它非頂級(jí)的對(duì)象訪問(wèn),需要使用#標(biāo)記。
          Struts2框架把OGNL Context設(shè)置為我們的ActionContext。并且ValueStack作為OGNL的根對(duì)象。除value stack之外,Struts2框架還把代表application、session、request這些對(duì)象的Map對(duì)象也放到ActionContext中去。(這也就是Struts2建議在Action類中不要直接訪問(wèn)Servlet API的原因,他可以通過(guò)ActionContext對(duì)象來(lái)部分代替這些(Servlet API)功能,以方便對(duì)Action類進(jìn)行測(cè)試?。?/span>
          Action的實(shí)例,總是放到value stack中。因?yàn)?/span>Action放在stack中,而stackroot(根對(duì)象),所以對(duì)Action中的屬性的訪問(wèn)就可以省略#標(biāo)記。但是,要訪問(wèn)ActionContext中其它對(duì)象的屬性,就必須要帶上#標(biāo)記,以便讓OGNL知道,不是從根對(duì)象,而是從其它對(duì)象中去尋找。
          那么訪問(wèn)Action中的屬性的代碼就可以這樣寫(xiě)

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

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

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

          ?

          ?

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

           值棧中的Action實(shí)例 
          Struts2框架總是把Action實(shí)例放在棧頂。因?yàn)?/span>Action在值棧中,而值棧又是OGNL中的根,所以引用Action的屬性可以省略“#”標(biāo)記,這也是為什么我們?cè)诮Y(jié)果頁(yè)面中可以直接訪問(wèn)Action的屬性的原因。

           Struts2中的命名對(duì)象 
          Struts2還提供了一些命名對(duì)象,這些對(duì)象沒(méi)有保存在值棧中,而是保存在ActionContext中,因此訪問(wèn)這些對(duì)象需要使用“#”標(biāo)記。這些命名對(duì)象都是Map類型。 

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

          request 
          用于訪問(wèn)請(qǐng)求屬性。如:#request['user']#request.user,相當(dāng)于調(diào)用了HttpServletRequest對(duì)象的getAttribute()方法。 

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

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

          attr 
          如果PageContext可用,則訪問(wèn)PageContext,否則依次搜索requestsessionapplication對(duì)象。

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


          posted @ 2014-01-09 11:20 kelly 閱讀(475) | 評(píng)論 (0)編輯 收藏
          1. 一、什么是OGNL,有什么特點(diǎn)?   
          2.   
          3. OGNL(Object-Graph Navigation Language),大概可以理解為:對(duì)象圖形化導(dǎo)航語(yǔ)言。是一種可以方便地操作對(duì)象屬性的開(kāi)源表達(dá)式語(yǔ)言。OGNL有如下特點(diǎn):    
          4.   
          5. 1、支持對(duì)象方法調(diào)用,形式如:objName.methodName();   
          6.   
          7. 2、支持類靜態(tài)的方法調(diào)用和值訪問(wèn),表達(dá)式的格式為@[類全名(包括包路)]@[方法名  值名],例如:   
          8.   
          9. @java.lang.String@format('foo %s''bar')或@tutorial.MyConstant@APP_NAME;   
          10.   
          11. 3、支持賦值操作和表達(dá)式串聯(lián),例如:   
          12.   
          13. price=100discount=0.8calculatePrice(),這個(gè)表達(dá)式會(huì)返回80;   
          14.   
          15. 4、訪問(wèn)OGNL上下文(OGNL context)和ActionContext;   
          16.   
          17. 5、操作集合對(duì)象。   
          18.   
          19.     
          20.   
          21. 二、使用OGNL表達(dá)式   
          22.   
          23. OGNL要結(jié)合struts標(biāo)簽來(lái)使用。由于比較靈活,也容易把人給弄暈,尤其是“%”、“#”、“$”這三個(gè)符號(hào)的使用。由于$廣泛應(yīng)用于EL中,這里重點(diǎn)寫(xiě)%和#符號(hào)的用法。   
          24.   
          25. 1、“#”符號(hào)有三種用途:   
          26.   
          27. (1)、訪問(wèn)非根對(duì)象(struts中值棧為根對(duì)象)如OGNL上下文和Action上下文,#相當(dāng)于ActionContext.getContext();下表有幾個(gè)ActionContext中有用的屬性:   
          28.   
          29.     
          30.   
          31. 名稱   
          32.  作用   
          33.  例子   
          34.     
          35. parameters   
          36.  包含當(dāng)前HTTP請(qǐng)求參數(shù)的Map   
          37.  #parameters.id[0]作用相當(dāng)于request.getParameter("id"   
          38.     
          39. request   
          40.  包含當(dāng)前HttpServletRequest的屬性(attribute)的Map   
          41.  #request.userName相當(dāng)于request.getAttribute("userName"   
          42.     
          43. session   
          44.  包含當(dāng)前HttpSession的屬性(attribute)的Map   
          45.  #session.userName相當(dāng)于session.getAttribute("userName"   
          46.     
          47. application   
          48.  包含當(dāng)前應(yīng)用的ServletContext的屬性(attribute)的Map   
          49.  #application.userName相當(dāng)于application.getAttribute("userName"   
          50.     
          51.   
          52. 注:attr 用于按request session application順序訪問(wèn)其屬性(attribute),#attr.userName相當(dāng)于按順序在以上三個(gè)范圍(scope)內(nèi)讀取userName屬性,直到找到為止。用于過(guò)濾和投影(projecting)集合,如books.{?#this.price<100};構(gòu)造Map,如#{'foo1':'bar1''foo2':'bar2'}。   
          53.   
          54.     
          55.   
          56. (2)、用于過(guò)濾和投影(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等標(biāo)簽賦值上。如果要在頁(yè)面中取一個(gè)map的值可以這樣寫(xiě):    
          63.   
          64. <s:property value="#myMap['foo1']"/>     
          65.   
          66. <s:property value="#myMap['foo1']"/>   
          67.   
          68. 2、“%”符號(hào)的用途是在標(biāo)簽的屬性值被理解為字符串類型時(shí),告訴執(zhí)行環(huán)境%{}里的是OGNL表達(dá)式。   
          69.   
          70. 這是一開(kāi)始最讓我不能理解的符號(hào),原因是一些相關(guān)資源在表述時(shí)不太準(zhǔn)備,經(jīng)過(guò)一翻痛苦的探索,終于明白了它的用途。實(shí)際上就是讓被理解為字符串的表達(dá)式,被真正當(dāng)成ognl來(lái)執(zhí)行。很有點(diǎn)類似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. 當(dāng)index變量為1時(shí),語(yǔ)句就會(huì)被當(dāng)作var oDiv document.all.div1  var oDiv document.all.div1來(lái)執(zhí)行。%{}就是起這個(gè)作用。舉例:    
          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行會(huì)在頁(yè)面上輸出“value1”,而第3行則會(huì)輸出"#myMap['key1']"這么一個(gè)字符串。 如果將第3行改寫(xiě)成這樣:    
          91.   
          92. <s:url value="%{#myMap['key1']}"/>     
          93.   
          94. <s:url value="%{#myMap['key1']}"/>   
          95.   
          96. 則輸出為“value1”。   
          97.   
          98.     
          99.   
          100.     
          101.   
          102. 這說(shuō)明struts2里不同的標(biāo)簽對(duì)ognl的表達(dá)式的理解是不一樣的。如果當(dāng)有的標(biāo)簽“看不懂”類似“#myMap['key1']”的語(yǔ)句時(shí),就要用%{}來(lái)把這括進(jìn)去,“翻譯”一下了。   
          103.   
          104. 3、“$”有兩種用途   
          105.   
          106. (1)、在國(guó)際化資源文件中,引用OGNL表達(dá)式。   
          107.   
          108. (2)、在Struts 2配置文件中,引用OGNL表達(dá)式:    
          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) | 評(píng)論 (0)編輯 收藏
               摘要: Ibatis介紹與用例   一、介紹 ibatis 是一種“半自動(dòng)化”的ORM實(shí)現(xiàn)。iBATIS是以SQL為中心的持久化層框架。能支持懶加載、關(guān)聯(lián)查詢、繼承等特性。iBATIS不同于一般的OR映射框架(eg:hibernate)。OR映射框架,將數(shù)據(jù)庫(kù)表、字段等映射到類、屬性,那是一種元數(shù)據(jù)(meta-data)映射。iBATIS則是將SQL查詢的參數(shù)和結(jié)果...  閱讀全文
          posted @ 2014-01-07 15:50 kelly 閱讀(369) | 評(píng)論 (0)編輯 收藏
               摘要: 深入Struts2的配置文件 本部分主要介紹struts.xml的常用配置。 1.1.    包配置: Struts2框架中核心組件就是Action、攔截器等,Struts2框架使用包來(lái)管理Action和攔截器等。每個(gè)包就是多個(gè)Action、多個(gè)攔截器、多個(gè)攔截器引用的集合。 在struts.xml文件中package元素用于定義包配置,每個(gè)pack...  閱讀全文
          posted @ 2014-01-07 15:39 kelly 閱讀(176) | 評(píng)論 (0)編輯 收藏
               摘要: 首頁(yè)要在web.xml中添加相應(yīng)的struts配置: <servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servle...  閱讀全文
          posted @ 2013-12-27 14:56 kelly 閱讀(195) | 評(píng)論 (0)編輯 收藏

          1   編寫(xiě)目的 

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

          2   適用對(duì)象 

            項(xiàng)目實(shí)施人員

          3   參考資料 

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

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

          4.2Tomcat下配置連接池 

          下面以tomcat5.5.26為例來(lái)介紹如何配置連接池

          1:需要的jar

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

          2:建立context文件

          進(jìn)入到conf\Catalina\localhost新建一個(gè)上下文文件,文件的名稱既為將來(lái)要訪問(wèn)是輸入url上下文名稱,例如我們建立一個(gè)名為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ù)庫(kù)連接相關(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默認(rèn)是org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory,tomcat也允許采用其他連接實(shí)現(xiàn),不過(guò)默認(rèn)使用dbcp。

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

          maxIdle="3"

          minIdle=”2”
          maxWait="5000"

          u
            應(yīng)對(duì)網(wǎng)絡(luò)不穩(wěn)定的策略

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

          u
          應(yīng)對(duì)連接泄漏的策略
          removeAbandoned="true"

          removeAbandonedTimeout="60"


          logAbandoned="true"

             

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

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

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

          maxActive="5"

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

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

          maxIdle="3"

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

          minIdle=2

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

          問(wèn)題:如何設(shè)置maxActive和maxIdle?

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


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

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

          testOnBorrow="true"

          validationQuery="select count(*) from bt_user"

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

          removeAbandoned="true"

          removeAbandonedTimeout="60"

          logAbandoned="true"

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

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

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

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

          posted @ 2013-12-17 11:03 kelly 閱讀(1541) | 評(píng)論 (0)編輯 收藏

                  將mysql數(shù)據(jù)文件導(dǎo)入到數(shù)據(jù)庫(kù)中:

                      1.在navicat 中創(chuàng)建一個(gè)mysql數(shù)據(jù)庫(kù)鏈接,填寫(xiě)端口、用戶名、密碼

                      2.創(chuàng)建數(shù)據(jù)庫(kù)

                      3.打開(kāi)數(shù)據(jù)庫(kù)

                      4.右鍵選擇“運(yùn)行sql文件”

                      5.選擇sql文件的地址并執(zhí)行

                      

                       用navicat將mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù)導(dǎo)出的兩種方法:

                       1.右鍵,轉(zhuǎn)儲(chǔ)sql文件,直接保存文件,不能設(shè)置執(zhí)行選項(xiàng)。

                       2.右鍵,數(shù)據(jù)傳輸;如果只想導(dǎo)出數(shù)據(jù)庫(kù)表結(jié)構(gòu),不導(dǎo)出數(shù)據(jù),可以把“數(shù)據(jù)傳輸”-》“高級(jí)”-》“記錄選項(xiàng)”中的勾去掉,則不會(huì)導(dǎo)出記錄。

          posted @ 2013-12-13 15:12 kelly 閱讀(290) | 評(píng)論 (0)編輯 收藏

          Windows 2008 R2默認(rèn)是禁止Ping的,但是我們?cè)谌粘V泻芏嗲闆r都需要用到Ping功能,這時(shí)候只需要打開(kāi)Ping功能即可。

          在防火期開(kāi)啟的狀態(tài)下,怎樣才能ping呢?

          開(kāi)始-控制面板-管理工具-服務(wù)器管理器,如圖


          選擇配置-高級(jí)安全 Windows 防火墻-入站規(guī)則:文件和打印機(jī)共享(回顯請(qǐng)求 - ICMPv4-In)(配置文件為域和公用的這條) 啟用該規(guī)則即可。
          在本地測(cè)試一下:ping ip,已經(jīng)通了!


          posted @ 2013-12-13 13:54 kelly 閱讀(278) | 評(píng)論 (0)編輯 收藏
          主站蜘蛛池模板: 剑阁县| 南皮县| 喜德县| 墨竹工卡县| 延津县| 礼泉县| 徐州市| 石首市| 萨迦县| 云安县| 柳江县| 灵山县| 盐津县| 修水县| 沭阳县| 新晃| 大邑县| 蒙阴县| 葵青区| 林西县| 康乐县| 星子县| 巴楚县| 涡阳县| 象州县| 巴彦淖尔市| 舟山市| 罗江县| 贵南县| 龙海市| 临江市| 剑川县| 白银市| 阜新市| 凤阳县| 清河县| 汽车| 攀枝花市| 巨野县| 涿鹿县| 秦安县|