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

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

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

    李李的技術(shù)博客

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      13 隨筆 :: 0 文章 :: 61 評論 :: 0 Trackbacks

    2005年10月7日 #

    為了降低侵入性,更好的被引用,對bba96核心部分進行了大量重構(gòu),去除了冗贅的層次與不必要的接口,并借助jdk5.0范型進行了代碼精簡。發(fā)布了bba96 tiger beta2,這個版本已經(jīng)是比較穩(wěn)定的版本,具體的改動如下

    • 去除所有的接口依賴,可直接在任何項目中直接調(diào)用
    • service的兩層合并為一層且去除service層的接口,但DAO曾仍保留接口以備擴展更多的orm實現(xiàn)
    • 增加sql execute的方法
    • 增強源自view的直接查詢能力
    • 參數(shù)名由原來難看的oriNames, oriOperators, oriStringValues改為直觀的searchName, searchOperator, searchValue
    • 增加了對QueryParam的toString功能,可打出對應(yīng)的sql,便于調(diào)試,參見com.bba96.tiger.util.QueryWebUtils的main函數(shù)

    下載頁面地址:https://bba96.dev.java.net/servlets/ProjectDocumentList?folderID=4149&expandFolder=4149&folderID=0

    如果你使用spring+hibernate,而又不喜歡hibernate criteria的麻煩,不妨嘗試一下bba96,你可以把主要精力放到業(yè)務(wù)方面。DefaultEntityManager提供了很多單層邏輯的便利方法給你使用,其中也包括執(zhí)行hsql或者sql查詢/更新的方法,如果你要多層次邏輯的條件查詢可以自己組裝QueryObject,參見com.bba96.tiger.util.QueryWebUtils的main函數(shù)。bba96還提供給你在view層自由增加查詢的能力。

    tiger版本僅提供了dao/service部分,所以如果你希望在view 查詢的安全性方面得到加強,可參考bba96 2.0其中的webwork view部分,權(quán)限部分也沒有包含在tiger中,希望盡快把包括例子的權(quán)限部分遷移過來,但還需要一點時間,最近在忙一個CMS的產(chǎn)品,時間不夠用啊……

    SpringSide項目中webwork MVC部分應(yīng)用到bba96 tiger對view部分的查詢,有興趣可以看看,這里也要推薦一下SpringSide,確實有很多很好的經(jīng)驗在里面可以借鑒。

    posted @ 2006-06-10 19:16 李李 閱讀(1578) | 評論 (2)編輯 收藏

    bba96 CHANGELOG
    ==========================
    http://bba96.dev.java.net

    Changes in version 2.0 alpha3 (2006.4.3)
    *fix action query parameters bug -- [XXX:...]
    *fix distinct bug (discard Criteria.DISTINCT_ROOT_ENTITY)
    *some minor improvement

    Changes in version 2.0 alpha2.2 (2006.3.16)
    *update webwork's jar for fixing example bug in weblogic
    *remove all contentType setting in example

    Changes in version 2.0 alpha2.1 (2006.3.8)
    *fix example bug
    *update readme.txt

    Changes in version 2.0 alpha1 (2006.3.7)
    *webwork 2.2 support
    *hibernate 3.x support, then support native sql
    *fix some bug
    *add aop security module
    *add action query parameters validation
    *enhance action query parameters management
    *support more logic in action query
    *support multi orderby property


    Changes in version 1.0 (2005.09.23)
    *release first


    源碼下載(包含兩個快速開發(fā)的例子。)
    https://bba96.dev.java.net/servlets/ProjectDocumentList?folderID=4149&expandFolder=4149&folderID=0

    簡介參見http://m.tkk7.com/scorpio_leon/archive/2005/11/09/18878.aspx

    posted @ 2006-03-08 01:24 李李 閱讀(1044) | 評論 (0)編輯 收藏

    很容易找到getText實際的操作類是LocalizedTextUtil,方法public static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, OgnlValueStack valueStack);

    java doc 如下

    Finds a localized text message for the given key, aTextName. Both the key and the message itself is evaluated as required. The following algorithm is used to find the requested message:

    1. Look for message in aClass' class hierarchy.
      1. Look for the message in a resource bundle for aClass
      2. If not found, look for the message in a resource bundle for any implemented interface
      3. If not found, traverse up the Class' hierarchy and repeat from the first sub-step
    2. If not found and aClass is a ModelDriven Action, then look for message in the model's class hierarchy (repeat sub-steps listed above).
    3. If not found, look for message in child property. This is determined by evaluating the message key as an OGNL expression. For example, if the key is user.address.state, then it will attempt to see if "user" can be resolved into an object. If so, repeat the entire process fromthe beginning with the object's class as aClass and "address.state" as the message key.
    4. If not found, look for the message in aClass' package hierarchy.
    5. If still not found, look for the message in the default resource bundles.
    6. Return defaultMessage

    主要就是查找resource bundle,下面說明一下
    1. 先查找該class(一般我們是在action調(diào)用,就是該action對應(yīng)的class了)對應(yīng)的properties文件,找不到再去找對應(yīng)的接口,找不到再去從該class的繼承樹上去重復(fù)前面的步驟。
    2. 如果是ModelDriver,以上找不到再以model的class去重復(fù)1的步驟
    3.繼續(xù)找,如果key是符合ognl表達式還以ognl表達式去解析類,如果能找到類,還以以上的步驟去查找
    4. 還找不到,就從根據(jù)package以及package的繼承樹去找,這還包括了該class的繼承樹所有的class的package樹(這一步存在了太多的重復(fù)查找工作,因為很多package都是相同的)
    5 使用默認的resource bundle

    java.util.ResourceBundle雖然有cache,但是ww為了減少調(diào)用getResourceBundle方法,也維護了一個miss的hashset,找不到的bundle name就丟進去,那么每一次查找都同步了這個miss,如果很多次查找,開銷也是很大的。

    我就舉一個例子,就說第四步查找package樹好了

            // nothing still? alright, search the package hierarchy now
            for (Class clazz = aClass;
                 (clazz 
    != null&& !clazz.equals(Object.class);
                 clazz 
    = clazz.getSuperclass()) {

                String basePackageName 
    = clazz.getName();
                
    while (basePackageName.lastIndexOf('.'!= -1) {
                    basePackageName 
    = basePackageName.substring(0, basePackageName.lastIndexOf('.'));
                    String packageName 
    = basePackageName + ".package";
                    msg 
    = getMessage(packageName, locale, aTextName, valueStack, args);

                    
    if (msg != null) {
                        
    return msg;
                    }

                    
    if (indexedTextName != null) {
                        msg 
    = getMessage(packageName, locale, indexedTextName, valueStack, args);

                        
    if (msg != null) {
                            
    return msg;
                        }
                    }
                }
            }

    假設(shè)你的action繼承樹是這樣
    com.bba96.core.webwork.actions.DefaultActionSupport
    com.xxxx.web.actions.XXXActionSupport
    com.xxxx.web.user.actions.UserAction
    com.xxxx.web.user.ViewUserAction
    且不說ww沒有判斷是否是com.opensymphony.xwork.ActionSupport或者ww的接口就停止,光是自己的繼承樹,就是4+3+3+3=13次,再加上往上的繼承樹以及對應(yīng)的接口,com.opensymphony.xwork.ActionSupport以及Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable, ContinuableObject的接口,查找次數(shù)超過30次甚至更多,這里的每一次都有一個同步miss的過程,開銷相當大。

    如果你的key所在的resource bundle沒有對應(yīng)到合適的class或package時,例如說放在了default bundle中,ww會浪費很多時間。這種情況下,我在沒有并發(fā)的時候測了一下,一次getText大概耗時40ms左右

    所以在實際應(yīng)用我們應(yīng)該避免這種情況出現(xiàn),要不讓resource bundle一一對應(yīng)class,要不就自己實現(xiàn)一個簡單的getText,其實要是ww的ActionSupport的textProvider允許改變就最好了。

    posted @ 2006-01-21 13:26 李李 閱讀(1627) | 評論 (0)編輯 收藏

       調(diào)試IIS+Tomcat,裝IIS的時候居然出現(xiàn)staxmem.dll不能復(fù)制,google了一下,居然很多人說要重裝才能解決,暈,又找到http://support.microsoft.com/?kbid=894351,根據(jù)上面說的,我是屬于method 2情況,但是沒有xp原盤,裝的時候就是sp2了,又倒……
      最后看到有人情況跟我的類似,就是用method 1的第一步 esentutl /p %windir%\security\database\secedit.sdb 就可以了%windir%那里應(yīng)該寫你的xp安裝路徑,不用管什么警告,確認就對了,IIS安裝成功……開始配置。
    posted @ 2005-12-21 23:29 李李 閱讀(1991) | 評論 (3)編輯 收藏

    一個例子,原來的

    <interceptor-ref name="validation"/>
    <interceptor-ref name="workflow"/>

    可改寫為
    <interceptor-ref name="validation">
        <param name="excludeMethods">input,back,cancel</param>
    </interceptor-ref>
    <interceptor-ref name="workflow">
        <param name="excludeMethods">input,back,cancel</param>
    </interceptor-ref>

    那么,對于簡單的需驗證頁面,不需要再因為避免不必要的校驗而分兩個action。

    只有com.opensymphony.xwork.validator.ValidationInterceptor, com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor 定義并實現(xiàn)了這個excludeMethods,實現(xiàn)的也還是比較粗糙的,我們在做類似實現(xiàn)的時候可以參考一下,有必要也可以改進,擴展一下,例如增加includeMethods
        public void setExcludeMethods(String excludeMethods) {
            
    this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods);
        }

        
    public String intercept(ActionInvocation invocation) throws Exception {
            
    if (excludeMethods.contains(invocation.getProxy().getMethod())) {
                log.debug(
    "Skipping workflow. Method found in exclude list.");
                
    return invocation.invoke();
            }
            
        }
    posted @ 2005-12-03 22:29 李李 閱讀(1527) | 評論 (2)編輯 收藏

    https://bba96.dev.java.net/servlets/ProjectDocumentList?folderID=4149&expandFolder=4149&folderID=0
    修正一處batchRemove的bug,
    將action的與持久化相關(guān)的方法,以及getResults方法保護起來
    添加了一個Book example. 包括簡單用戶管理,書籍的查詢與租借。
    Book Example 參見 http://book.bba96.com
    Advanced Example 參見 http://www.gopherbook.com


    posted @ 2005-11-18 09:37 李李 閱讀(496) | 評論 (0)編輯 收藏

    https://bba96.dev.java.net/
    源文件下載
    https://bba96.dev.java.net/servlets/ProjectDocumentList?folderID=4149&expandFolder=4149&folderID=0


    1. 核心持久層部分基于spring/hibernate,實現(xiàn)強大靈活的動態(tài)query功能,可獨立使用。
    2. 權(quán)限部分,基于RBAC,支持數(shù)據(jù)權(quán)限,依賴1部分的接口。
    3. Action層,基于1以及webwork,良好架構(gòu),減少大量代碼,支持view靈活進行query且有參數(shù)教驗支持保證安全性。

    簡單說bba96就是基于hibernate/spring的快速開發(fā)框架,其中包含了對Hibernate Critiera,Projection的封裝,通過一個強大而靈活的QueryObject對象,方便動態(tài)添加與刪除條件。
    通過統(tǒng)一的query與數(shù)據(jù)庫交互,方便AOP,其中的RBAC權(quán)限模塊(支持數(shù)據(jù)權(quán)限)即是通過AOP操作QueryObject對象來實現(xiàn)的。bba96核心可以跟流行的view整合,目前只有webwork整合的版本。

    bba96 不再需要自己寫DAO/SERVICE,借助簡單的spring ioc即可配置使用缺省DAO/SERVICE,而且通過靈活方便,易擴展的后臺持久層與webwork的整合,完全實現(xiàn)了快速開發(fā)的目的。


    Get Up And Running Quick

    Example:
    ?? (1) enter the example/simple or emample/book folder.
    ?????? NOTE:all following operation is under the folder you entered
    ?? (2) copy your JDBC driver (default mysql) to the lib directory
    ?????? -- webapps\ROOT\WEB-INF\lib
    ?? (3) edit hibernate.properties for database info (default mysql)
    ?????? -- src\main\java\hibernate.properties
    ?? (4) run "ant"
    ?? (5) create database via the sql script generated at database\schema-export.sql
    ?? (6) edit applicationContext.xml for database info (default mysql)
    ?????? -- webapps\ROOT\WEB-INF\applicationContext.xml (line 5 - 21)
    ?? (7) start server and see this example


    有使用上的討論,請聯(lián)系我 MSN: hotmail的帳號scorpio_leon
    posted @ 2005-11-09 00:51 李李 閱讀(6389) | 評論 (45)編輯 收藏

    1. 如果你用hibernate+spring,注意spring的OpenSessionInView的Filter要在webwork的Filter之前
    2. ww:property這個tag缺省是escape html的,在tag可以指定escape="false"避免html字符轉(zhuǎn)義
    3. 一些原來用單引號表示字符串的都要去掉單引號,例如 " 'test' "  要改為 "test"
    4. No object in the CompoundRoot has a property named,這是由于在webwork.properties設(shè)置了webwork.devMode=true,會檢查頁面上傳遞過來的參數(shù)是否在action定義過。
    posted @ 2005-10-19 15:36 李李 閱讀(854) | 評論 (1)編輯 收藏

    public interface ModelDriven {
        Object getModel();
    }

    而我需要的是
    public interface ModelDriven {
        Object getModel() 
    throws Exception;
    }

    因為要攔截可能拋出的異常,流程是這樣service - my service interceptor - action - xwork interceptor
    現(xiàn)在斷在action這里了,很奇怪,webwork其他方法都有throw exception,獨獨這個沒有,難道又要hack webwork?
    恩,有了AOP后,接口設(shè)計應(yīng)該要多考慮一下,是否允許拋出異常……

    posted @ 2005-10-18 18:22 李李 閱讀(619) | 評論 (1)編輯 收藏

    看看下面的應(yīng)用例子,程序執(zhí)行三秒后會在后臺開始發(fā)Email,只有幾行程序,很簡單吧。
    本來就應(yīng)該這么簡單,還能再省么,呵呵,謝謝開源的力量……

        SimpleEmail email = new SimpleEmail();
        email.addTo(
    "receiver@somemail.com""Receier's Name");
        email.setSubject(
    "Email from www.bba96.com");
        email.setMsg(
    "Hello, guy!");
        EmailScheduler emailScheduler 
    = new EmailScheduler();
        emailScheduler.process(email);

    這里用到了jakarta common email中的SimpleEmail
    EmailScheduler是一個利用Opensymphony Quartz做簡單的調(diào)度,其中EmailJob實現(xiàn)了Quartz的Job接口
    以下是EmailScheduler以及EmailJob源代碼。

    package com.bba96.scheduler;

    import java.util.Date;

    import javax.mail.Authenticator;

    import org.apache.commons.mail.Email;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleTrigger;

    public class EmailScheduler {

        
    public void process(Email email, Authenticator authenticator)
                
    throws SchedulerException {
            
    // TODO if can be optimized with static instance.
            SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
            Scheduler sched 
    = schedFact.getScheduler();
            sched.start();

            JobDetail jobDetail 
    = new JobDetail("EmailJob"null, EmailJob.class);
            jobDetail.getJobDataMap().put(EmailJob.EMAIL, email);
            jobDetail.getJobDataMap().put(EmailJob.AUTHENTICATIOR, authenticator);
            
    //Create a trigger that fires exactly once, three seconds from now
            long startTime = System.currentTimeMillis() + 3000L;
            SimpleTrigger trigger 
    = new SimpleTrigger("emailTrigger"null,
                    
    new Date(startTime), null00L);
            sched.scheduleJob(jobDetail, trigger);
        }

        
    public void process(Email email) throws SchedulerException {
            process(email, 
    null);
        }

    }

     

    package com.bba96.scheduler;

    import javax.mail.Authenticator;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.commons.mail.DefaultAuthenticator;
    import org.apache.commons.mail.Email;
    import org.apache.commons.mail.EmailException;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;

    public class EmailJob implements Job {

        
    protected final Log logger = LogFactory.getLog(EmailJob.class);

        
    public static String EMAIL = "EMAIL";

        
    public static String AUTHENTICATIOR = "AUTHENTICATIOR";

        
    public static String DEFAULT_HOST = "your smtp mail server";

        
    public static int DEFAULT_SMTP_PORT = 25;

        
    public static String DEFAULT_USER = "yourmail@yourserver.com";

        
    public static String DEFAULT_PASSWORD = "your password";

        
    public static String DEFAULT_FROM_ADDRESS = "yourmail@yourserver.com";

        
    public static String DEFAULT_FROM_NAME = "Your Name";

        
    public void execute(JobExecutionContext context)
                
    throws JobExecutionException {
            Email email 
    = (Email) context.getJobDetail().getJobDataMap().get(EMAIL);
            
    if (email != null) {
                Authenticator authenticator 
    = (Authenticator) context
                        .getJobDetail().getJobDataMap().get(AUTHENTICATIOR);
                
    if (email.getHostName() == null) {
                    email.setHostName(DEFAULT_HOST);
                }
                
    if (email.getSmtpPort() == null) {
                    email.setSmtpPort(DEFAULT_SMTP_PORT);
                }
                
    if (authenticator == null) {
                    authenticator 
    = new DefaultAuthenticator(DEFAULT_USER,
                            DEFAULT_PASSWORD);
                    email.setAuthenticator(authenticator);
                }
                
    if (email.getFromAddress() == null) {
                    
    try {
                        email.setFrom(DEFAULT_FROM_ADDRESS, DEFAULT_FROM_NAME);
                    } 
    catch (EmailException e) {
                        logger.error(
    "Email address invalid", e);
                        
    return;
                    }
                }
                
    try {
                    email.send();
                } 
    catch (EmailException e) {
                    logger.error(
    "Email send error", e);
                }
            }
        }

    }

    posted @ 2005-10-15 22:01 李李 閱讀(2108) | 評論 (0)編輯 收藏

    原來用著一個朋友的手機最近經(jīng)常沒信號,不得不換一個,還是用回Nokia,6030,還很不錯。偶很喜歡,咔咔

    ……

    為什么今天上來寫兩句,不是無聊……因為心情很郁悶,很郁悶很郁悶…… Sigh, MM真是太作了,痛苦……

    bba96申請畢業(yè)總算有回應(yīng)了,dev.java.net來信說bba96 example不錯,希望把binary文件也放上去,有助于用戶嘗試……找個時間放上去吧。另外用properties文件在加強參數(shù)安全性的校驗,限定所接受的nameTypes, oriOperators, stringValues的范圍,這樣,就可以兼顧靈活性與安全高興了。

    有空也可以整理整理那個RBAC權(quán)限的框架,成熟了也放到dev.java.net上吧。
    posted @ 2005-10-14 18:04 李李 閱讀(368) | 評論 (0)編輯 收藏

    今天嘗試了一下SkypeOut,打到國外確實比普通IP電話省錢,平均0.20-0.30/分鐘。音質(zhì)還不錯:D
    posted @ 2005-10-07 02:52 李李 閱讀(286) | 評論 (1)編輯 收藏

    主站蜘蛛池模板: 情人伊人久久综合亚洲| 久久久久亚洲国产AV麻豆| 成人免费黄色网址| 亚洲av无码有乱码在线观看| 亚洲麻豆精品国偷自产在线91| 国产在线观看免费视频软件| 国产亚洲精品免费视频播放| 亚洲成片观看四虎永久| 久久美女网站免费| 亚洲欧美成aⅴ人在线观看| 中国亚洲女人69内射少妇| 久久成人国产精品免费软件| 日韩黄色免费观看| h视频免费高清在线观看| 亚洲成A∨人片在线观看无码| 免费观看国产小粉嫩喷水| 久久大香伊焦在人线免费| 成人婷婷网色偷偷亚洲男人的天堂| 亚洲国产a∨无码中文777 | 午夜电影免费观看| 久久青草免费91线频观看不卡 | 亚洲AV无码一区二区乱子伦| 国产日韩精品无码区免费专区国产| 亚洲自偷自拍另类图片二区| 亚洲?v无码国产在丝袜线观看| 57PAO成人国产永久免费视频| 黄床大片免费30分钟国产精品| 亚洲男人天堂2018av| 亚洲第一AAAAA片| 亚洲国产成人久久一区久久| 在线永久免费的视频草莓| a级片免费观看视频| 亚洲综合在线观看视频| 精品亚洲一区二区三区在线观看| 91情侣在线精品国产免费| 日本免费久久久久久久网站| 一级毛片一级毛片免费毛片| 伊人久久亚洲综合影院首页| 精品亚洲A∨无码一区二区三区| 亚洲免费日韩无码系列| 国产小视频在线观看免费|