1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      在Struts框架下使用時間類型

      更新時間: 2007-05-14 11:17:24來源: 粵嵌教育瀏覽量:830


        使用時間類型?這誰不會,不就是java.util下的幾個類嗎,在不加上java.sql和java.text下的幾個類,這會有什么問題嗎?Struts要是連時間都處理不了,那還能干嘛?在實際應用中,我就發現Struts確實連有些簡單的時間都處理不了(不知是我使用的方法不對還是Struts確實沒有考慮到)。順便你也能了解Struts是怎么把form里的請求參數populate到ActionForm里面的。
        
        今天下午同事告訴我把有java.util.Date類型屬性的類存入數據庫時出錯,把這個屬性刪除就沒有問題了。當時我就想到是RequestProcessor在processPopulate()時出錯了,因此在它的這個方法設了斷點并跟蹤了進去。當然,它要調用ActionForm的reset()方法,然后調用實際處理populate(將請求參數傳給ActionForm)的RequestUtils.populate()方法。RequestUtils的這個靜態方法是處理Multipart的(即文件上傳等多部分)的方法,然后將所有的請求都放在叫properties的HashMap里并循環處理它:
            names = request.getParameterNames();
            while (names.hasMoreElements()) {
              String name = (String) names.nextElement();
              String stripped = name;
              if (prefix != null) {
                if (!stripped.startsWith(prefix)) {
                  continue;
                }
                stripped = stripped.substring(prefix.length());
              }
              if (suffix != null) {
                if (!stripped.endsWith(suffix)) {
                  continue;
                }
                stripped = stripped.substring(0, stripped.length() - suffix.length());
              }
              if (isMultipart) {
                properties.put(stripped, multipartParameters.get(name));
              } else {
                properties.put(stripped, request.getParameterValues(name));
              }
            }
        
        實際處理它們的是下面的:BeanUtils.populate(bean, properties); 其中bean就是接受數據的ActionForm,而properties里面則是所有的請求的鍵-值對(鍵和值都是字符串,http協議的特點)。
        
        再看看BeanUtils的靜態(類)方法populate是怎么處理的:
            // Loop through the property name/value pairs to be set
            Iterator names = properties.keySet().iterator();
            while (names.hasNext()) {
        
              // Identify the property name and value(s) to be assigned
              String name = (String) names.next();
              if (name == null) {
                continue;
              }
              Object value = properties.get(name);
        
              // Perform the assignment for this property
              setProperty(bean, name, value);
        
            }
        它是循環所有的請求參數,把實際的工作又交給了setProperty方法。呵呵,弄了半天,這幫人原來都是代理。
        
        這個方法還是代理嗎?計算了一下它有180行的代碼。這么長應該是個實干家了吧,錯!千萬不要被有些人的外表欺騙了!有些人上班16個小時,可夠敬業的,可有8小時在打CS。這個類就是:一上來20多行都在一個if (log.isTraceEnabled()){}里面。
        
        log在這說明一下。Struts中使用的是Jakarta Commons Logging的包,它使用的優先級是:Log4j(4念four好像比較有意義,大概是Logger For Java的意思,我聽有的人年Log si J,感覺很別扭,呵呵),Java 1.4 Logging API,Simple Logging。功能是依次減弱。
        
        建議在寫Action 的execute()或被execute()調用的業務方法中使用Commons Logging 來代替System.out.println()--當要你把成百上千的System.out.println()去掉的時候你就會覺得Commons Logging是個多好的東東了。它的用法是:
         import org.apache.commons.logging.Log;
         import org.apache.commons.logging.LogFactory;
            private/protected static Log log = LogFactory.getLog(DispatchAction.class);
        如果你用的是DispatchAction,那你就不要自己定義Log的實例了,因為它已經有一個protected的Log實例,直接使用即可。
        
        使用方法是:
            if (log.isInfoEnabled()) {
               log.Info("some information.");
            }
        Logging把消息分為6種級別,debug,error,fatal,info,trace,warn。比如,你想記錄一條消息,它只是為了給用戶一個警告,則可以使用warn。為什么在每個log.Info()前做一次判斷呢?難道如果log級別不允許Info,log.Info()仍然能Info嗎?當然不是。它的作用是提高效率。
        
        比如有個消息是計算前一萬個自然數的和(這種消息可能少見)。用直接log.Info()
            int sum=0;
            for(int i=0;i<10000;i++){
             sum+=i;
            }
            log.Info("the sum of form 1 to 10000 is : "_sum);
        如果log.Info是不允許的,那求10000個數的和就白求的。當然如果你的計算機很快或和高斯一樣聰明,直接log.Info()也每什么問題。
           
        閑話少說,回到180多行的BeanUtils.setProperty()方法。這個方法先是處理nested屬性,也就是xxx.xxx的請求參數。我們只看看處理簡單屬性的必須過程。下面這端代碼有點長,但它只做了一件事:將字符串的請求參數轉成ActionForm的類型。比如:你在ActionForm里有個Integer userAge;然后HTTP請求參數里可能會有http://localhost:8080/xxx.do?userAge=21。傳人的是字符串,目標是專程Integer。
        
        首先它當然會根據userAge這個字符串查找相應的ActionForm,如果這個ActionForm有個屬性也叫userAge,然后就會把這個userAge的類型存到type里,type的定義是:Class type = null; 得到type的代碼很長,這是因為要它考慮很多情況,例如DynaActionForm。
           // Convert the specified value to the required type
            Object newValue = null;
            if (type.isArray() && (index < 0)) { // Scalar value into array
              if (value == null) {
                String values[] = new String[1];
                values[0] = (String) value;
                newValue = ConvertUtils.convert((String[]) values, type);
              } else if (value instanceof String) {
                String values[] = new String[1];
                values[0] = (String) value;
                newValue = ConvertUtils.convert((String[]) values, type);
              } else if (value instanceof String[]) {
                newValue = ConvertUtils.convert((String[]) value, type);
              } else {
                newValue = value;
              }
            } else if (type.isArray()) {     // Indexed value into array
              if (value instanceof String) {
                newValue = ConvertUtils.convert((String) value,
                                type.getComponentType());
              } else if (value instanceof String[]) {
                newValue = ConvertUtils.convert(((String[]) value)[0],
                                type.getComponentType());
              } else {
                newValue = value;
              }
            } else {               // Value into scalar
              if ((value instanceof String) || (value == null)) {
                newValue = ConvertUtils.convert((String) value, type);
              } else if (value instanceof String[]) {
                newValue = ConvertUtils.convert(((String[]) value)[0],
                                type);
              } else if (ConvertUtils.lookup(value.getClass()) != null) {
                newValue = ConvertUtils.convert(value.toString(), type);// Here is my program's break point
              } else {
                newValue = value;
              }
            }
        
        是:調用PropertyUtils的一些方法設置值。下面代碼的種情況是有索引的,即你在請求參數里傳了field[0]=123之類的參數,第二種是Map類型的,傳的是map(key)=value之類的參數,一般的就是調用第三個方法。
              if (index >= 0) {
                PropertyUtils.setIndexedProperty(target, propName,
                                 index, newValue);
              } else if (key != null) {
                PropertyUtils.setMappedProperty(target, propName,

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 日韩欧美自拍中文字幕 | 曰韩精品视频一区二区 | 日本中文一二区有码在线 | 日韩一级一欧美一级国产 | 在线点播亚洲日韩国产欧美 | 伊人久久精品一区二区三区 |