云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Tapestry中并沒有類似于Spring Security這樣的專門的權(quán)限框架。對(duì)此Tapestry的作者Lewis認(rèn)為主要是用戶對(duì)于權(quán)限的要求實(shí)在太多變化了。他認(rèn)為很難抽象出一個(gè)通用的權(quán)限框架來滿足所有的用戶,所以他干脆就不費(fèi)事去做這件事了。但其實(shí)我們很容易就能利用Tapestry已有的工具來完成類似于SpringSecurity的功能。
          本文主要介紹如何實(shí)現(xiàn)類似于SpringSecurity的jsp tag的功能。在Tapestry中,利用Components實(shí)現(xiàn)這一點(diǎn)非常容易。
          其基本原理是Tapestry5中一個(gè)頁(yè)面或者組件的渲染生成過程是基于一個(gè)狀態(tài)機(jī)和隊(duì)列完成的。這樣,渲染生成過程就被細(xì)分成了很多個(gè)小模塊,我們可以非常容易地覆寫這些小模塊。具體內(nèi)容詳見官方文檔:http://tapestry.apache.org/tapestry5.1/guide/rendering.html。如果權(quán)限校驗(yàn)不通過,我們就可以控制不顯示組件的內(nèi)容。
          我們這里就是主要依賴這個(gè)過程來實(shí)現(xiàn)在頁(yè)面這一層面對(duì)權(quán)限進(jìn)行校驗(yàn)和控制。
          代碼主要包含兩大部分,一個(gè)組件和一個(gè)用于權(quán)限控制的服務(wù)。
          參考了Tapestry-Spring-Security的實(shí)現(xiàn),我也將組件命名為IfRole(當(dāng)然,我們也可以和Tapestry-Spring-Security一樣,也再生成一個(gè)IfLoggedIn組件)。權(quán)限控制的服務(wù)我命名為:AuthenticationService。
          主要的實(shí)現(xiàn)思路:
          將AuthenticationService申明為SessionState變量。這樣這個(gè)變量就可以在所有的頁(yè)面和組件之間很方便地共享了。一般情況下,是在登錄頁(yè)面對(duì)AuthenticationService進(jìn)行賦值,而在退出頁(yè)面清空AuthenticationService這個(gè)變量。
          代碼(這部分代碼完全根據(jù)應(yīng)用的需求進(jìn)自行更改):
          AuthenticationService的代碼:
          public class AuthenticationService {
              
          private List<String> privilegeList;
              
          // privilegeList 的getter and setter

              
          public boolean checkPermission(String ifNotGranted, String ifAllGranted,
                      String ifAnyGranted) 
          {
                  
          if (((null == ifAllGranted) || "".equals(ifAllGranted))
                          
          && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
                          
          && ((null == ifNotGranted) || "".equals(ifNotGranted))) {
                      
          return false;
                  }


                  
          if ((null != ifNotGranted) && !"".equals(ifNotGranted)) {
                      StringTokenizer st 
          = new StringTokenizer(ifNotGranted, ",");
                      
          while (st.hasMoreTokens()) {
                          String value 
          = st.nextToken();
                          
          if (privilegeList.contains(value)) {
                              
          return false;
                          }

                      }

                  }


                  
          if ((null != ifAllGranted) && !"".equals(ifAllGranted)) {
                      StringTokenizer st 
          = new StringTokenizer(ifAllGranted, ",");
                      
          while (st.hasMoreTokens()) {
                          String value 
          = st.nextToken();
                          
          if (!privilegeList.contains(value)) {
                              
          return false;
                          }

                      }

                  }


                  
          if ((null != ifAnyGranted) && !"".equals(ifAnyGranted)) {
                      StringTokenizer st 
          = new StringTokenizer(ifAnyGranted, ",");
                      
          while (st.hasMoreTokens()) {
                          String value 
          = st.nextToken();
                          
          if (privilegeList.contains(value)) {
                              
          return true;
                          }

                      }

                      
          return false;
                  }


                  
          return true;
              }

          }

          IfRole的代碼(這個(gè)類需要放在Components目錄下):
          public class IfRole {
              
          /**
               * A comma-separated list of roles is supplied to one or more of the
               * following parameters. If none are supplied, the default behavior is to
               * forbid access. Behavior should be self-explanatory.
               
          */

              @Parameter(required 
          = false, defaultPrefix = "literal")
              
          private String ifAllGranted;

              @Parameter(required 
          = false, defaultPrefix = "literal")
              
          private String ifAnyGranted;

              @Parameter(required 
          = false, defaultPrefix = "literal")
              
          private String ifNotGranted;

              
          /**
               * An alternate {
          @link Block} to render if the test parameter is false. The default, null, means
               * render nothing in that situation.
               
          */

              @Parameter(name 
          = "else")
              
          private Block elseBlock;

              
          private boolean test;
             
              @SessionState
              
          private AuthenticationService auth;

              
          private boolean checkPermission() {
                  
          return auth.checkPermission(ifNotGranted, ifAllGranted, ifAnyGranted);
              }

             
              
          void setupRender() {
                  test 
          = checkPermission();
              }


              
          /**
               * Returns null if the test method returns true, which allows normal
               * rendering (of the body). If the test parameter is false, returns the else
               * parameter (this may also be null).
               
          */

              Object beginRender() 
          {
                  
          return test ? null : elseBlock;
              }


              
          /**
               * If the test method returns true, then the body is rendered, otherwise not. The component does
               * not have a template or do any other rendering besides its body.
               
          */

              
          boolean beforeRenderBody() {
                  
          return test;
              }

             
          }


          示例:
          1. 在登錄頁(yè)面:
          @SessionState
          private Authentication auth;

          ......

          // if user name and password is valid:
          auth.setPrivliegeList(.....);


          2. 在需要權(quán)限控制的頁(yè)面模板中:
          <t:ifRole ifAllGranted="admin">
                  administrator can see this block
          </t:ifRole>

          posted @ 2010-01-12 20:17 云自無心水自閑 閱讀(2862) | 評(píng)論 (0)編輯 收藏

          與現(xiàn)在最流行的SSH相比較,Tapestry能夠完全替代其中Struts2和Spring,但是他還是需要一個(gè)ORM的框架。IBatis由于比較低的學(xué)習(xí)曲線,也受到很多人的喜愛。尤其是在IBatis3中引入了許多新的概念和想法,使用更加安全和便利。
          本文主要介紹如何將Tapestry5.1和IBatis3進(jìn)行整合。
          簡(jiǎn)要步驟:
          1. 準(zhǔn)備工作
          2. 數(shù)據(jù)庫(kù)的建立
          3. POJO的建立
          4. IBatis相關(guān)配置文件的創(chuàng)建
          5. Tapestry相關(guān)代碼的完成
          概要說明:
          1、準(zhǔn)備工作。這一部分是比較簡(jiǎn)單的,Eclipse之類的開發(fā)環(huán)境是必需的。Tapestry5.1、IBatis3(目前還是Beta7)、數(shù)據(jù)庫(kù)(我使用的是MySql)的下載安裝。
          2、數(shù)據(jù)庫(kù)的建立,由于是示例,所以數(shù)據(jù)庫(kù)的建立也非常簡(jiǎn)單,只有一張User表,3個(gè)字段,Id,Name,Password
          3、com.sample.User類,對(duì)應(yīng)數(shù)據(jù)庫(kù)表的3個(gè)字段,生成User類
          4、IBatis配置文件:Configuration.xml,UserMapper.xml,jdbc.properties的生成, 前兩個(gè)必需,最后一個(gè)可選.
          5、在AppModule里,使用build方法, 添加服務(wù)生成IBatis3的SqlSessionFactory, 在需要使用SqlSessionFactory的地方,使用@InjectService注入即可
          詳細(xì)說明:
          1、大家到各自的網(wǎng)站上下載相應(yīng)的包好了。我只羅列一下我所用到的Lib:
              antlr-runtime-3.1.1.jar
              commons-codec-1.3.jar
              commons-lang-2.4.jar
              ibatis-3-core-3.0.0.216.jar
              javassist.jar
              log4j-1.2.14.jar
              mysql-connector-java-5.0.5.jar
              slf4j-api-1.5.10.jar
              slf4j-log4j12-1.5.10.jar
              stax2-api-3.0.1.jar
              tapestry-core-5.1.0.5.jar
              tapestry-ioc-5.1.0.5.jar
              tapestry5-annotations-5.1.0.5.jar
              woodstox-core-lgpl-4.0.7.jar
          2、Create Table
          DROP TABLE IF EXISTS `test`.`user`;
          CREATE TABLE  `test`.`user` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `name` varchar(45) NOT NULL,
            `password` varchar(45) NOT NULL,
            PRIMARY KEY (`id`)
          ) ENGINE=InnoDB;

          3、
          package com.sample.model;
          public class User {
              private long id;
              private String name;
              private String password;
              // getter and setter    ....
          }

          4、我把Configuration.xml和UserMapper.xml都放在src目錄下,這樣在部署的時(shí)候,就是生成在classes,也就是類路徑的根目錄下。
          Configuration.xml:
          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE configuration
            PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
            "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> 
          <configuration>
              <properties resource="jdbc.properties">
              </properties>
              <environments default="development">
                  <environment id="development">
                      <transactionManager type="JDBC"/>
                      <dataSource type="POOLED">
                          <property name="driver" value="${jdbc.driver}"/>
                          <property name="url" value="${jdbc.url}"/>
                          <property name="username" value="${jdbc.username}"/>
                          <property name="password" value="${jdbc.password}"/>
                          <property name="poolPingEnabled" value="${pingenable}"/>           
                          <property name="poolPingQuery" value="${pingquery}"/>           
                          <property name="poolPingConnectionsNotUsedFor" value="${pingnotusetime}"/>           
                      </dataSource>
                  </environment>
              </environments>
              <mappers>
                  <mapper resource="UserMapper.xml"/>
              </mappers>
          </configuration>


          UserMapper.xml:
          <?xml version="1.0" encoding="UTF-8" ?> 
          <!DOCTYPE mapper 
              PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" 
              "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
             
          <mapper namespace="com.sample.model.UserMapper">
              <select id="selectUser" parameterType="int" resultType="com.sample.model.User"> 
                  select * from user where id = #{id} 
              </select>
          </mapper>



          jdbc.properties:
          jdbc.driver=com.mysql.jdbc.Driver
          jdbc.url=jdbc:mysql://localhost/test?autoReconnect=true
          jdbc.username=root
          jdbc.password=root
          pingenable=true
          pingquery=SELECT 1
          pingoldertime=0
          pingnotusetime=3600000

          5、
          package com.sample.web.services;
          public class AppModule {
              public static SqlSessionFactory buildSqlSessionFactory() {
                  try {
                      String resource = "Configuration.xml";
                      Reader reader = Resources.getResourceAsReader(resource);
                      return new SqlSessionFactoryBuilder().build(reader);
                  } catch (Exception e) {
                      logger.warn("failed to build SqlSessionFactory: ", e);
                      return null;
                  }
              }

              private static Logger logger = LoggerFactory.getLogger(AppModule.class);
          }


          package com.sample.model;
          public interface UserMapper {
              public User selectUser(int id);
          }


          package com.pc.sample.web.pages;
          public class Layout {
              @InjectService("SqlSessionFactory")
              private SqlSessionFactory sqlMapper;
              public String getUserName() {
                  if ( sqlMapper == null ) {
                      return "null-mapper";
                  }
                  SqlSession session = sqlMapper.openSession();
                  try {
                      UserMapper userMapper = session.getMapper(UserMapper.class);
                      if ( userMapper == null ) {
                          return "null-userMapper";
                      }
                      User user = userMapper.selectUser(1);
                      if ( user == null ) {
                          return "null-user";
                      }
                      return user.getName();
                  } catch (Exception e) {
                      return "exception-" + e.getMessage();
                  } finally {
                      session.close();
                  }
              }
          }

          幾個(gè)注意事項(xiàng):
          1, 因?yàn)槲业腎Batis的配置文件Configuration.xml是放在類路徑的根目錄下,所以在初始化SqlSessionFactory的時(shí)候,直 接用String resource = "Configuration.xml";就行了,否則需要添加相應(yīng)的路徑,比如:把Configuration.xml與User類放在一起,也就是在 com.sample.model這個(gè)package中,那么就要寫成:String resource = "com/sample/model/Configuration.xml";
          同樣,在Configuration.xml中,指定UserMapper.xml的規(guī)則也是這樣的。
          2,UserMapper的使用。Mapper的使用是IBatis3中才有的新功能,也是IBatis用戶指南中推薦使用的方式。因?yàn)檫@樣使用的話,就完全避免了類型的強(qiáng)制轉(zhuǎn)換,實(shí)現(xiàn)了類型安全。
          需要注意的是UserMapper只是一個(gè)接口。我們不需要提供這個(gè)接口的具體實(shí)現(xiàn)。IBatis3會(huì)自動(dòng)生成一個(gè)具體的實(shí)例。

          其中的方法名必須與UserMapper.xml中的select語句的id一樣。在我的例子中是selectUser.
          另外,此方法的返回值的類型必須與UserMapper.xml中配置的returnType一致。
          最后要提醒的是UserMapper.xml中的namespace必須是UserMapper的全類名,在本例中就是com.sample.model.UserMapper

          posted @ 2010-01-06 12:20 云自無心水自閑 閱讀(3101) | 評(píng)論 (2)編輯 收藏

          here is a summary of key features in Spring 3.0 overall:

          * Spring expression language (SpEL): a core expression parser for use in bean definitions, allowing for references to nested bean structures (e.g. properties of other beans) as well as to environmental data structures (e.g. system property values) through a common #{…} syntax in property values.


          * Extended support for annotation-based components: now with the notion of configuration classes and annotated factory methods (as known from Spring JavaConfig). Spring also allows for injecting configuration values through @Value expressions now, referring to configuration settings via dynamic #{…} expressions or static ${…} placeholders.

          * Powerful stereotype model: allows for creating 'shortcut' annotations through the use of meta-annotations, e.g. for default scopes and default transactional characteristics on custom stereotypes. Imagine a custom @MyService annotation indicating @Service, @Scope("request") and @Transactional(readOnly=true) through a single annotation.

          * Standardized dependency injection annotations: Spring 3.0 comes with full support for the JSR-330 specification for Dependency Injection in Java – annotation-driven injection via @Inject and its associated qualifier and provider model, as an alternative to Spring's own @Autowired and co.

          * Declarative model validation based on constraint annotations: Spring-style setup of a JSR-303 Bean Validation provider (such as Hibernate Validator 4.0). Comes with an annotation-driven validation option in Spring MVC, exposing a unified view on constraint violations through Spring’s binding result facility.

          * Enhanced binding and annotation-driven formatting: Converter and Formatter SPIs as an alternative to standard PropertyEditors. Formatting may be driven by annotations in a style similar to JSR-303 constraints, e.g. using @DateTimeFormat. Also, check out the new mvc namespace for convenient setup of formatting and validation in Spring MVC.

          * Comprehensive REST support: native REST capabilities in Spring MVC, such as REST-style request mappings, URI variable extraction through @PathVariable parameters, and view resolution driven by content negotiation. Client-side REST support is available in the form of a RestTemplate class.

          * Rich native Portlet 2.0 support: Spring MVC fully supports Portlet 2.0 environments and Portlet 2.0’s new event and resource request model. Includes specialized mapping facilities for typical portlet request characteristics: @ActionMapping, @RenderMapping, @ResourceMapping, @EventMapping.

          * Object/XML Mapping (OXM): as known from Spring Web Services, now in Spring Framework core. Marshalling and Unmarshaller abstractions with out-of-the-box support for JAXB 2, Castor, etc. Comes with integration options for XML payloads in Spring MVC and Spring JMS.

          * Next-generation scheduling capabilities: new TaskScheduler and Trigger mechanisms with first-class cron support. Spring 3.0 comes with a convenient task namespace and also supports @Async and @Scheduled annotations now. This can be executed on top of native thread pools or server-managed thread pools.

          Beyond those big themes, there are hundreds of refinements in the details which you will particularly appreciate when upgrading from Spring 2.5. Check the changelog and the javadocs…

          In terms of system requirements, Spring 3.0 covers a broad range of environments. For two key characteristics, Spring 3.0 supports Java SE 5 and above and Servlet 2.4 and above, e.g. Tomcat 5.x and 6.x, also retaining compatibility with common enterprise servers such as WebSphere 6.1 and WebLogic 9.2 (which are formally still based on J2EE 1.4). At the same time, we support GlassFish v3 already – adapting to Java EE 6 API level in Spring as well.

          As a consequence, Spring 3 brings brand-new component model features, and also standards like JSR-330 injection and JSR-303 validation, to established production environments – without having to upgrade your server installation! All you have to do is to upgrade the application libraries of your Spring-powered application to Spring 3.0…

          Enjoy – and watch out for follow-up posts about specific Spring 3 features, as well as for samples running on Spring 3.0!

          posted @ 2009-12-17 14:44 云自無心水自閑 閱讀(1211) | 評(píng)論 (1)編輯 收藏

          struts2的文件上傳對(duì)文件大小的限制,缺省值是2m,也就是說缺省情況下,最大只能上傳2m的文件。根據(jù)文檔所說需要對(duì)fileUpload這個(gè)攔截器的一個(gè)參數(shù)maximunSize進(jìn)行設(shè)置

          <interceptor-ref name="fileUpload">
                  <param name="maximumSize">1000000</param>
                  <param name="allowedTypes">image/gif,image/jpeg,image/jpg,image/png</param>
          </interceptor-ref>

          但是我設(shè)置了之后并沒有作用。
          后來,仔細(xì)查看日志后才發(fā)現(xiàn)錯(cuò)誤是commons-fileupload里面的文件大小限制引起了錯(cuò)誤。
          在struts.xml中,添加
          <constant name="struts.multipart.maxSize" value="16777216"/>
          解決問題!

          posted @ 2009-11-19 13:44 云自無心水自閑 閱讀(5523) | 評(píng)論 (2)編輯 收藏

               摘要: JavaRebel是一個(gè)工具,主要是用于熱加載,比如說在Tomcat之類的應(yīng)用服務(wù)器中,更新了class或者某些資源文件,使用了JRebel之后,就不需要重新啟動(dòng)應(yīng)用服務(wù)器。這對(duì)于開發(fā)的人來說,是特別方便的。當(dāng)然Java也提供了HotSpot的JVM,但是如果你修改的類中有方法名稱變動(dòng)的話,HotSpot就無能為力了,必須要重要啟動(dòng)應(yīng)用服務(wù)器。 這里有一點(diǎn)先聲明一下,本文只是破解僅限于學(xué)習(xí)和研究...  閱讀全文

          posted @ 2009-10-15 20:09 云自無心水自閑 閱讀(11327) | 評(píng)論 (16)編輯 收藏

          目前從實(shí)際應(yīng)用來看,ORM的老大自然是Hibernate,可是iBatis因?yàn)橄鄬?duì)比較直觀、學(xué)習(xí)曲線相對(duì)較低,因而也贏得了不少用戶的青睞。
          本文主要介紹作為iBatis輔助工具的iBator的使用方法。
          iBator是一個(gè)iBatis相關(guān)代碼的自動(dòng)生成工具。
          1、安裝iBator的插件
          在Eclipse中,使用添加站點(diǎn)的方法,輸入網(wǎng)址http://ibatis.apache.org/tools/ibator,進(jìn)行iBator的安裝。
          2、建議不要直接在使用iBatis的項(xiàng)目里直接使用iBator,推薦另外單獨(dú)建立一個(gè)項(xiàng)目來生成。比如,建立一個(gè)項(xiàng)目叫:IbatorPrj
          3、右鍵點(diǎn)擊IbatorPrj這個(gè)項(xiàng)目,如果剛才的插件安裝正確的話,就會(huì)看到一個(gè)“Add iBATOR to the build path”的選項(xiàng),點(diǎn)擊一下。
          4、創(chuàng)建iBator的配置文件。下面是我的例子,大家在實(shí)際使用的過程中,需要根據(jù)自己的情況進(jìn)行相應(yīng)的修改。
          主要就是數(shù)據(jù)庫(kù)JDBC庫(kù)的路徑、數(shù)據(jù)庫(kù)驅(qū)動(dòng)的類名、項(xiàng)目的名稱、包名等。
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE ibatorConfiguration
            PUBLIC "-//Apache Software Foundation//DTD Apache iBATIS Ibator Configuration 1.0//EN"
            "http://ibatis.apache.org/dtd/ibator-config_1_0.dtd">

          <ibatorConfiguration>
                  <classPathEntry location="c:\javaLibs\MySql\mysql-connector-java-5.0.6-bin.jar" />

                  <ibatorContext id="SampleiBator" targetRuntime="Ibatis2Java5">
                          <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                                  connectionURL="jdbc:mysql://localhost/sample" userId="root" password="admin">
                          </jdbcConnection>

                          <javaTypeResolver>
                                  <property name="forceBigDecimals" value="false" />
                          </javaTypeResolver>

                          <javaModelGenerator targetPackage="com.sample"
                                  targetProject="IbatorPrj\src">
                                  <property name="enableSubPackages" value="true" />
                                  <property name="trimStrings" value="true" />
                          </javaModelGenerator>

                          <sqlMapGenerator targetPackage="com.sample.xml"
                                  targetProject="IbatorPrj\src">
                                  <property name="enableSubPackages" value="true" />
                          </sqlMapGenerator>

                          <daoGenerator type="GENERIC-CI" targetPackage="com.sample.dao"
                                  targetProject="IbatorPrj\src">
                                  <property name="enableSubPackages" value="true" />
                          </daoGenerator>

                          <table schema="sample" tableName="tab1" domainObjectName="JavaBean1">
                                  <property name="useActualColumnNames" value="false" />
                                  <generatedKey column="ID" sqlStatement="MySql" identity="true" />
                          </table>

                  </ibatorContext>
          </ibatorConfiguration>
          5、配置文件生成完畢后,右鍵點(diǎn)擊這個(gè)文件,選擇“Generate iBatis Artifact”,然后你就在配置的文件夾下找到自動(dòng)生成的文件了。

          posted @ 2009-10-07 20:18 云自無心水自閑 閱讀(3938) | 評(píng)論 (6)編輯 收藏

               摘要: Tapestry IoC容器從歷史上來說,是從從HiveMind繼承發(fā)展而來,但是HiveMind和目前大紅大紫的Spring都不能滿足Tapestry的一些特定的需求,所以全新開發(fā)了一套IoC的容器。
          其核心思想就是使用Java代碼自身來解決依賴注入而不是由Xml之類的配置文件來完成,這和Guice的思想是非常相似的,Lewis也承認(rèn)從Guice那里借鑒了不少。
          另外需要說明一下的是,Tapesty還從中國(guó)的一個(gè)非常古老但又充滿哲理的游戲--圍棋中借鑒了一些術(shù)語和思想。大意是圍棋中經(jīng)常要把棋子走的輕盈(Lightness),讓每個(gè)棋子都能盡量地高效。編程也一樣要輕量(Lightness)。  閱讀全文

          posted @ 2009-09-12 22:07 云自無心水自閑 閱讀(2448) | 評(píng)論 (1)編輯 收藏

          在應(yīng)用中一般普通的JavaPojo都是由Spring來管理的,所以使用autowire注解來進(jìn)行注入不會(huì)產(chǎn)生問題,但是有兩個(gè)東西是例外的,一個(gè)是Filter,一個(gè)是Servlet,這兩樣?xùn)|西都是由Servlet容器來維護(hù)管理的,所以如果想和其他的Bean一樣使用Autowire來注入的話,是需要做一些額外的功夫的。
          對(duì)于Filter,Spring提供了DelegatingFilterProxy,所以本文主要講述Servlet的解決。
          1、比較直觀但是不大優(yōu)雅的做法是重寫init()方法,在里面使用AutowireCapableBeanFactory來手工告訴Spring:我這個(gè)Servlet是需要這樣的一個(gè)Bean的。具體寫法:
          public void init(ServletConfig servletConfig) throws ServletException {
              ServletContext servletContext = servletConfig.getServletContext();
              WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
              AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext.getAutowireCapableBeanFactory();
              autowireCapableBeanFactory.configureBean(this, BEAN_NAME);
          }
          其中,BEAN_NAME就是需要注入的Bean在spring中注冊(cè)的名字.
          這樣寫的主要問題是就是那個(gè)BEAN_NAME,這樣寫有點(diǎn)主動(dòng)查找,而不是依賴注入的感覺。

          2、創(chuàng)建一個(gè)類似于DelegatingFilterProxy那樣的代理,通過代理根據(jù)配置來找到實(shí)際的Servlet,完成業(yè)務(wù)邏輯功能。
          假定我們有一個(gè)Servlet名字叫UserServlet,需要注入一個(gè)UserManager,偽代碼如下:
          public class UserServlet extends HttpServlet {
              @Autowired(required = true)
              private UserManager userManager;
          }
          第一步:
          public class DelegatingServletProxy extends GenericServlet {
              private String targetBean;
              private Servlet proxy;

              @Override
              public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
                  proxy.service(req, res);
              }

              @Override
              public void init() throws ServletException {
                  this.targetBean = getServletName();
                  getServletBean();
                  proxy.init(getServletConfig());
              }

              private void getServletBean() {
                  WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
                  this.proxy = (Servlet) wac.getBean(targetBean);
              }
          }
          第二步:
          配置web.xml文件,原來UserServlet的配置大致是這樣的:
              <servlet>
                  <servlet-name>userServlet</servlet-name>
                  <servlet-class>com.sample.UserServlet</servlet-class>
              </servlet>

              <servlet-mapping>
                  <servlet-name>userServlet</servlet-name>
                  <url-pattern>/userServlet</url-pattern>
              </servlet-mapping>
          現(xiàn)在修改為
              <servlet>
                  <servlet-name>userServlet</servlet-name>
                  <servlet-class>com.sample.DelegatingServletProxy</servlet-class>
              </servlet>

              <servlet-mapping>
                  <servlet-name>userServlet</servlet-name>
                  <url-pattern>/userServlet</url-pattern>
              </servlet-mapping>
          注意,spring是根據(jù)Servlet的名字來查找被代理的Servlet的,所以,首先我們要在UserServlet類前面加上@Component,來告訴Srping:我也是一個(gè)Bean。如果名稱和Web.xml里面定義的不一樣的話,可以在這里指定Bean的名字,比如: @Component("userServlet")


          posted @ 2009-09-04 14:19 云自無心水自閑 閱讀(6565) | 評(píng)論 (2)編輯 收藏

          在我的隨筆Extjs Tree + JSON + Struts2中我介紹了如何異步加載一個(gè)Extjs的樹,但是很多網(wǎng)友留言說不能成功操作。現(xiàn)在我自己做了一個(gè)所有源代碼的包,供大家下載。
          有幾點(diǎn)事項(xiàng)請(qǐng)大家注意
          1、blogjava的文件上載要求單個(gè)文件不能超過4M,所以,我把web-inf目錄下的所有jar文件刪除了。
          所有jar文件的列表是:
          commons-beanutils-1.7.0.jar
          commons-collections-3.2.jar
          commons-digester-1.6.jar
          commons-lang-2.3.jar
          commons-logging-1.1.jar
          dom4j-1.6.1.jar
          ezmorph-1.0.4.jar
          freemarker-2.3.8.jar
          javassist-3.8.1.jar
          json-lib-2.2.1-jdk15.jar
          log4j-1.2.13.jar
          ognl-2.6.11.jar
          struts2-core-2.0.11.jar
          xml-apis-1.0.b2.jar
          xwork-2.0.4.jar
          注意紅色標(biāo)記的那個(gè)jar文件是上次隨筆中遺漏了的。這個(gè)文件是需要的。
          2、blogjava要求上傳文件不能是war文件,所以我把war文件改成了rar后綴。
          文件的URL: war文件下載

          posted @ 2009-09-01 11:07 云自無心水自閑 閱讀(7469) | 評(píng)論 (14)編輯 收藏

          struts2中conventions plugin的url取名規(guī)則:
          假設(shè)有一個(gè)類:com.example.actions.HelloWorld,
          Struts2會(huì)自動(dòng)搜索所有實(shí)現(xiàn)了com.opensymphony.xwork2.Action接口或者在struts.xml中<constant name="struts.convention.package.locators" value="actions"/> 指定的包下的類。
          現(xiàn)存HelloWorld只是一個(gè)POJO,但是他在actions包下,這樣Struts2就認(rèn)可這是一個(gè)Action.
          那么URL會(huì)是什么呢?是hello-world,類似于:http://localhost:8080/<contextPath>/hello-world.action.
          如果你不喜歡這樣的自動(dòng)分配的URL,那么可以在里面的方法使用@Action來改變
          @Action("/helloWorld")
          public void execute() throws Exception {
              return "success";
          }

          posted @ 2009-08-24 14:25 云自無心水自閑 閱讀(578) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共29頁(yè): First 上一頁(yè) 8 9 10 11 12 13 14 15 16 下一頁(yè) Last 
          主站蜘蛛池模板: 什邡市| 南康市| 枝江市| 乐都县| 蒙阴县| 寿光市| 汨罗市| 桐梓县| 澳门| 庐江县| 时尚| 乌鲁木齐县| 临沧市| 苏尼特左旗| 当阳市| 闸北区| 伊金霍洛旗| 周宁县| 霍林郭勒市| 酒泉市| 育儿| 桃园市| 黔西县| 泌阳县| 蚌埠市| 宁城县| 搜索| 清新县| 佳木斯市| 沽源县| 西平县| 鹤岗市| 南丹县| 漳浦县| 浑源县| 南汇区| 集贤县| 阳城县| 英超| 泾川县| 龙陵县|