隨筆 - 10, 文章 - 0, 評論 - 7, 引用 - 0
          數(shù)據(jù)加載中……

          2007年5月20日

          關(guān)于appfuse的探討

                項(xiàng)目在緊張的生活中很快就要結(jié)束了,一直以來,都是由于工作的繁忙,沒有時(shí)間去寫自己的blog.這段時(shí)間終于可以稍微閑下來了,覺得應(yīng)該把這一階段的工作總結(jié)一下了,但是拿起鍵盤,思緒卻有些散亂,想寫的很多,卻也不知道怎么來寫,還是慢慢來吧.
             首先說一下整體框架appfuse,它是集成了當(dāng)今最流行的web應(yīng)用框架的更高層次的web開發(fā)框架.也可以說是一個(gè)web開發(fā)的基本平臺,它將當(dāng)前最流行的一些技術(shù),比如hibernate,spring,struts,DBUnit,ant,log4j,xdoclet,sitemesh,velocity,jstl,webwork,等等都集成了進(jìn)來,在國內(nèi)能夠?qū)⑦@些都應(yīng)用進(jìn)來的并不多見.

          待續(xù)....

          posted @ 2007-06-07 23:56 LiuTing 閱讀(251) | 評論 (0)編輯 收藏

          JS常見函數(shù)

          1.常規(guī)函數(shù)  
            javascript常規(guī)函數(shù)包括以下9個(gè)函數(shù):  
            (1)alert函數(shù):顯示一個(gè)警告對話框,包括一個(gè)OK按鈕。  
            (2)confirm函數(shù):顯示一個(gè)確認(rèn)對話框,包括OK、Cancel按鈕。  
            (3)escape函數(shù):將字符轉(zhuǎn)換成Unicode碼。  
            (4)eval函數(shù):計(jì)算表達(dá)式的結(jié)果。  
            (5)isNaN函數(shù):測試是(true)否(false)不是一個(gè)數(shù)字。  
            (6)parseFloat函數(shù):將字符串轉(zhuǎn)換成符點(diǎn)數(shù)字形式。  
            (7)parseInt函數(shù):將符串轉(zhuǎn)換成整數(shù)數(shù)字形式(可指定幾進(jìn)制)。  
            (8)prompt函數(shù):顯示一個(gè)輸入對話框,提示等待用戶輸入。例如:  
            (9)unescape函數(shù):解碼由escape函數(shù)編碼的字符。  
            2.數(shù)組函數(shù)  
            javascript數(shù)組函數(shù)包括以下4個(gè)函數(shù):  
            (1)join函數(shù):轉(zhuǎn)換并連接數(shù)組中的所有元素為一個(gè)字符串。例:  
           
           程序代碼  
              function JoinDemo()  
              {  
               var a, b;  
               a = new Array(0,1,2,3,4);  
               b = a.join("-");//分隔符  
               return(b);//返回的b=="0-1-2-3-4"  
              }   
             
           (2)langth函數(shù):返回?cái)?shù)組的長度。例:  
                 
           程序代碼  
          function LengthDemo()  
              {  
               var a, l;  
               a = new Array(0,1,2,3,4);  
               l = a.length;  
               return(l);//l==5  
              }   
           
            (3)reverse函數(shù):將數(shù)組元素順序顛倒。例:  
                
           程序代碼  
          function ReverseDemo()  
             {  
              var a, l;  
              a = new Array(0,1,2,3,4);  
              l = a.reverse();  
              return(l);  
             }   
            (4)sort函數(shù):將數(shù)組元素重新排序。例:  
                 
           程序代碼  
          function SortDemo()  
              {  
               var a, l;  
               a = new Array("X" ,"y" ,"d", "Z", "v","m","r");  
               l = a.sort();  
               return(l);  
              }   
            3.日期函數(shù)  
            javascript日期函數(shù)包括以下20個(gè)函數(shù):  
            (1)getDate函數(shù):返回日期的“日”部分,值為1~31。例:  
                
           程序代碼  
          function DateDemo()  
             {  
              var d, s = "Today's date is: ";  
              d = new Date();  
              s += (d.getMonth() + 1) + "/";  
              s += d.getDate() + "/";  
              s += d.getYear();  
              return(s);  
             }   
            (2)getDay函數(shù):返回星期幾,值為0~6,其中0表示星期日,1表示星期一,...,6表示星期六。例:  
                
           程序代碼  
          function DateDemo()  
             {  
              var d, day, x, s = "Today is: ";  
              var x = new Array("Sunday", "Monday", "Tuesday");  
              var x = x.concat("Wednesday","Thursday", "Friday");  
              var x = x.concat("Saturday");  
              d = new Date();  
              day = d.getDay();  
              return(s += x[day]);  
             }   
            (3)getHouse函數(shù):返回日期的“小時(shí)”部分,值為0~23。例。  
                
           程序代碼  
          function TimeDemo()  
             {  
              var d, s = "The current local time is: ";  
              var c = ":";  
              d = new Date();  
              s += d.getHours() + c;  
              s += d.getMinutes() + c;  
              s += d.getSeconds() + c;  
              s += d.getMilliseconds();  
              return(s);  
             }   
            (4)getMinutes函數(shù):返回日期的“分鐘”部分,值為0~59。見上例。  
            (5)getMonth函數(shù):返回日期的“月”部分,值為0~11。其中0表示1月,2表示3月,...,11表示12月。見前面的例子。  
            (6)getSeconds函數(shù):返回日期的“秒”部分,值為0~59。見前面的例子。  
            (7)getTime函數(shù):返回系統(tǒng)時(shí)間。  
                
           程序代碼  
          function GetTimeTest()  
             {  
              var d, s, t;  
              var MinMilli = 1000 * 60;  
              var HrMilli = MinMilli * 60;  
              var DyMilli = HrMilli * 24;  
              d = new Date();  
              t = d.getTime();  
              s = "It's been " 
              s += Math.round(t / DyMilli) + " days since 1/1/70";  
              return(s);  
             }   
            (8)getTimezoneOffset函數(shù):返回此地區(qū)的時(shí)差(當(dāng)?shù)貢r(shí)間與GMT格林威治標(biāo)準(zhǔn)時(shí)間的地區(qū)時(shí)差),單位為分鐘。  
                
           程序代碼  
          function TZDemo()  
             {  
              var d, tz, s = "The current local time is ";  
              d = new Date();  
              tz = d.getTimezoneOffset();  
           
              if (tz 的鏈接點(diǎn)的名稱,另一個(gè)函數(shù)link設(shè)定的URL地址。  
            (2)big函數(shù):將字體加到一號,與...標(biāo)簽結(jié)果相同。  
            (3)blink函數(shù):使字符串閃爍,與...標(biāo)簽結(jié)果相同。  
            (4)bold函數(shù):使字體加粗,與...標(biāo)簽結(jié)果相同。  
            (5)charAt函數(shù):返回字符串中指定的某個(gè)字符。  
            (6)fixed函數(shù):將字體設(shè)定為固定寬度字體,與...標(biāo)簽結(jié)果相同。  
            (7)fontcolor函數(shù):設(shè)定字體顏色,與標(biāo)簽結(jié)果相同。  
            (8)fontsize函數(shù):設(shè)定字體大小,與標(biāo)簽結(jié)果相同。  
            (9)indexOf函數(shù):返回字符串中第一個(gè)查找到的下標(biāo)index,從左邊開始查找。  
            (10)italics函數(shù):使字體成為斜體字,與...標(biāo)簽結(jié)果相同。  
            (11)lastIndexOf函數(shù):返回字符串中第一個(gè)查找到的下標(biāo)index,從右邊開始查找。  
            (12)length函數(shù):返回字符串的長度。(不用帶括號)  
            (13)link函數(shù):產(chǎn)生一個(gè)超級鏈接,相當(dāng)于設(shè)定的URL地址。  
            (14)small函數(shù):將字體減小一號,與...標(biāo)簽結(jié)果相同。  
            (15)strike函數(shù):在文本的中間加一條橫線,與...標(biāo)簽結(jié)果相同。  
            (16)sub函數(shù):顯示字符串為下標(biāo)字(subscript)。  
            (17)substring函數(shù):返回字符串中指定的幾個(gè)字符。  
            (18)sup函數(shù):顯示字符串為上標(biāo)字(superscript)。  
            (19)toLowerCase函數(shù):將字符串轉(zhuǎn)換為小寫。  
            (20)toUpperCase函數(shù):將字符串轉(zhuǎn)換為大寫。  
           
          //校驗(yàn)是否全由數(shù)字組成  
           
           程序代碼  
          function isDigit(s)  
          {  
          var patrn=/^[0-9]{1,20}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)登錄名:只能輸入5-20個(gè)以字母開頭、可帶數(shù)字、“_”、“.”的字串  
           
           程序代碼  
          function isRegisterUserName(s)  
          {  
          var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)用戶姓名:只能輸入1-30個(gè)以字母開頭的字串  
           
           程序代碼  
          function isTrueName(s)  
          {  
          var patrn=/^[a-zA-Z]{1,30}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)密碼:只能輸入6-20個(gè)字母、數(shù)字、下劃線  
           
           程序代碼  
          function isPasswd(s)  
          {  
          var patrn=/^(\w){6,20}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)普通電話、傳真號碼:可以“+”開頭,除數(shù)字外,可含有“-”  
           
           程序代碼  
          function isTel(s)  
          {  
          //var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?(\d){1,12})+$/;  
          var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)手機(jī)號碼:必須以數(shù)字開頭,除數(shù)字外,可含有“-”  
           
           程序代碼  
          function isMobil(s)  
          {  
          var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)郵政編碼  
           
           程序代碼  
          function isPostalCode(s)  
          {  
          //var patrn=/^[a-zA-Z0-9]{3,12}$/;  
          var patrn=/^[a-zA-Z0-9 ]{3,12}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
          //校驗(yàn)搜索關(guān)鍵字  
           
           程序代碼  
          function isSearch(s)  
          {  
          var patrn=/^[^`~!@#$%^&*()+=|\\\][\]\{\}:;\'\,.<>/?]{1}[^`~!@$%^&()+=|\\\][\]\{\}:;\'\,.<>?]{0,19}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  
           
           程序代碼  
          function isIP(s) //by zergling  
          {  
          var patrn=/^[0-9.]{1,20}$/;  
          if (!patrn.exec(s)) return false 
          return true 
          }  

          posted @ 2007-05-29 18:03 LiuTing 閱讀(300) | 評論 (0)編輯 收藏

          DISPALYTAG的用法

          1) Caption指標(biāo)題
          2) name:數(shù)據(jù)源
          3) defaultsort:排序列,一般不需要
          4) defaultorder:排序方式
          5) class:表格顯示的樣式
          6) varTotals:需要統(tǒng)計(jì)(總計(jì))
          7) decorator="totals":表示使用指定的decorator。現(xiàn)在僅在同時(shí)使用小計(jì)、合計(jì)時(shí)用到,自己也可以定制。
          8) <display:column 部分:
            property指數(shù)據(jù)中的列名
            title指顯示的標(biāo)題
            format指數(shù)據(jù)的格式化樣式,
            total表示該字段是否需要作統(tǒng)計(jì)。
            style="width:20%"可以設(shè)置寬度。
            也可以用
            <display:column title="請假時(shí)間">
            <fmt:formatDate value="${currentRowObject.QJSJ}" pattern="yyyy-MM-dd"/>
            </display:column>表現(xiàn)。
            group="1"表示進(jìn)行g(shù)roup的字段。
          9) 在表格中建立一個(gè)連接:
            <display:column title="部別">
            <a href="<c:out value="${pageContext.request.contextPath}"/>
            /holidayDefaultSearchStatView.do?type=
            <c:out value="${currentRowObject.CJDM}"/>&SYD=
            <c:out value="${currentRowObject.DWDM}"/>" target="_blank">
            <c:out value="${currentRowObject.DWMC}"/>
            </a>
            </display:column>
          10) 由于該tag只有合計(jì)時(shí),沒有合計(jì)那一列,所以實(shí)現(xiàn)的時(shí)候以<display:footer>實(shí)現(xiàn)。
            可以通過totalMap對象獲取合計(jì)的數(shù)據(jù),如totalMap.colomn1獲取合計(jì)的第一列數(shù)值。
          11) 標(biāo)題頭不顯示<display:setProperty name="basic.show.header" value="false" />
          12) 自己定制表頭:<display:caption>
             使用decorator:
             <jsp:scriptlet>
             org.displaytag.decorator.TotalTableDecorator totals =
             new org.displaytag.decorator.TotalTableDecorator();
                 totals.setTotalLabel("合計(jì)");
                 totals.setSubtotalLabel("小計(jì)");
                 pageContext.setAttribute("totals", totals);
             </jsp:scriptlet>
          實(shí)例:
          <display:caption>這是表標(biāo)題</display:caption>
           <display:table
            name="${model.rowToColumnStatResult}" defaultsort="1"
            class="simple" defaultorder="ascending" varTotals="totalMap">
            <display:column property="GCWZ" title="部門"/>
             <c:forEach items="${model.YList.YList}" var="yColumn">
             <c:forEach items="${model.rowToColumnStatResult[0]}"
                var="mapEntry">
              <c:if test="${mapEntry.key == yColumn}">
               <th>
                 <display:column property="${mapEntry.key}"
                 title="${mapEntry.key}"
                 format="{0,number,####.##}" total="true"/>
               </th>
              </c:if>
             </c:forEach>
             </c:forEach>
            <display:column property="小計(jì)"
                title="小計(jì)"
                format="{0,number,####.##}" total="true"/>
           <display:footer>
           <tr>
            <td>總計(jì)</td>
            <c:forEach items="${model.YList.YColumn}" var="yColumn">
            <td><fmt:formatNumber value="${totalMap[yColumn]}"
                  pattern="####.##"/>
            </td>
            </c:forEach>
           </tr>
           </display:footer>
          </display:table>
           

          另外一個(gè)例子:
          <display:table name="${model.statResult}" class="simple"
           varTotals="totalMap">
           <display:column property="XMMC" title="項(xiàng)目名稱" />
           <display:column property="KSRQ" title="開始日期" />
           <display:column property="FZRXM" title="負(fù)責(zé)人姓名" />
           <display:column property="GKDW" title="掛靠單位" />
           <display:column property="JFLY" title="經(jīng)費(fèi)來源" />
           <display:column property="XMZJF" title="項(xiàng)目總經(jīng)費(fèi)" total="true" />
           <display:column property="DNDKJF" title="當(dāng)年到款經(jīng)費(fèi)" total="true"/>
           <display:footer>
            <tr><td colspan="5">總計(jì)</td>
             <td>
              <fmt:formatNumber value="${totalMap.column6}"
               pattern="####.####" />
             </td>
             <td>
              <fmt:formatNumber value="${totalMap.column7}"
               pattern="####.####" />
             </td>
            </tr>
           </display:footer>
          </display:table>
          總計(jì)某一列的方法:
          ${totalMap.column?}    ?為該列號
          colspan="5":表示這個(gè)單元格占5個(gè)單元格
          項(xiàng)目名稱 開始日期  負(fù)責(zé)人姓名 掛靠單位 經(jīng)費(fèi)來源 項(xiàng)目總經(jīng)費(fèi) 當(dāng)年到款經(jīng)費(fèi)
                                                             531      400
                                                             151       10
          -------------------------------------
          總計(jì)                              682     500 

          posted @ 2007-05-25 10:42 LiuTing 閱讀(760) | 評論 (0)編輯 收藏

          DWRUtils API 使用方法

          $("precloneNode1suf") 取得該對象;

          DWRUtil.selectRange("selectRangeBasic", 5, 15) 選中selectRangeBasic文本框里面從第五個(gè)字符到第15個(gè)字符之間的字符.

          DWRUtil._getSelection("selectRangeBasic") 得到selectRangeBasic文本框里選中的字符.

          var arrayFive = [ 'One', 'Two', 'Three', 'Four', 'Five' ];
          DWRUtil.addOptions('addOptionsBasic', arrayFive); 將數(shù)組添加到下拉菜單里面去;

          DWRUtil.getValue('addOptionsBasic') 得到 addOptionsBasic 對象的值;
          DWRUtil.getValue("precloneNode1Inner1suf", { textContent:true }); 后面加個(gè)參數(shù),在 precloneNode1Inner1suf元素為"UL" 時(shí),它返回了元素里面得值,也就是說去掉了HTML標(biāo)簽部分.

          DWRUtil.getText('addOptionsBasic') 得到下拉框 addOptionsBasic 顯示的文本;

          var arrayObject = [
          { name:'One', value:'1' },
          { name:'Two', value:'2' },
          { name:'Three', value:'3' },
          { name:'Four', value:'4' },
          { name:'Five', value:'5' }
          ];
          DWRUtil.addOptions('addOptionsObject1', arrayObject, "name"); 將數(shù)組添加到下拉菜單里面去;后面的參數(shù)是確定那個(gè)是給用戶顯示的文本,同時(shí)也是值;

          DWRUtil.addOptions('addOptionsObject1', arrayObject, "name","value"); 同上,不過后面參數(shù)是: 3=文本;4=值;

          var map = { one:1, two:2, three:3, four:4, five:5 };
          DWRUtil.addOptions('addOptionsMap1', map); 同上, one 是值;1 是文本;
          DWRUtil.addOptions('addOptionsMap1', map,true); 同上, 1 是值;one 是文本;

          -------------------------------------------------------------------------------------
          <ul id="removeItems">
          <li>One</li><li>Two</li><li>Three</li><li>Four</li><li>Five</li>
          </ul>

          如果是列表顯示,如上;則上面所有方法和select 下拉框使用一樣;
          -------------------------------------------------------------------------------------
          DWRUtil.cloneNode('cloneNode1', { idPrefix:'pre', idSuffix:'suf' });克隆一個(gè)節(jié)點(diǎn),參數(shù)一為要克隆的節(jié)點(diǎn)的id,第二個(gè)參數(shù)是在克隆的節(jié)點(diǎn)id前面加pre,后面加suf.(注意:如果該節(jié)點(diǎn)有子節(jié)點(diǎn)的話,子節(jié)點(diǎn)的名字也一樣加)

          DWRUtil.addRows(id, array, cellfuncs, [options]);
          原理:

          for each member in array
          for each function in cellfuncs
          create cell from cellfunc(array[i])
          循環(huán)數(shù)組,循環(huán)函數(shù),建立單元調(diào)用函數(shù);(順序決定)

          例如:
          DWRUtil.addRows('addRowsBasic', arrayFive, [
          function(data) { return data; },
          function(data) { return data.toUpperCase(); },
          function(data) {
          var input = document.createElement("input");
          input.setAttribute("type", "button");
          input.setAttribute("value", "DOM Test");
          input.setAttribute("onclick", "alert('" + data + "');");
          return input;
          },
          function(data) { return "<input type='button' value='innerHTML Test' onclick='alert(\"" + data + "\");'>"; }
          ]);

          高級部分:
          第四個(gè)參數(shù)為對單元的高級操作,主要下面的兩個(gè)方法;
          function defaultRowCreator(options) {
          return document.createElement("tr");
          };

          function defaultCellCreator(options) {
          return document.createElement("td");
          };

          例子:
          DWRUtil.addRows( "demo2",[ 'Africa', 'America', 'Asia', 'Australasia', 'Europe' ] , cellFuncs, {
          rowCreator:function(options) {
          var row = document.createElement("tr");
          var index = options.rowIndex * 50;
          row.style.color = "rgb(" + index + ",0,0)";
          return row;
          },
          cellCreator:function(options) {
          var td = document.createElement("td");
          var index = 255 - (options.rowIndex * 50);
          td.style.backgroundColor = "rgb(" + index + ",255,255)";
          td.style.fontWeight = "bold";
          return td;
          }
          });

          其中 options 參數(shù)的屬性可用的為:(沒試過,自己試試吧)

          rowData: the element value from the array (the same for all cells in a row)
          rowIndex: the key (if map) or index (if array) from the collection
          rowNum: The row number counting from 0 in this section (so if you are using tbody, it counts rows in the tbody and not the whole table)
          data: The 'computed' data value for the cell (cellCreators only)
          cellNum: The cell number that we are altering counting from 0 (cellCreators only)


          DWRUtil.setValues(); 批量設(shè)置值;
          var settings = {
          setValuesDiv:"setValuesDiv",
          setValuesSpan:"setValuesSpan",
          setValuesSelect:"two",
          setValuesText:"setValuesText",
          setValuesPassword:"AB",
          setValuesTextarea:"setValuesTextarea",
          setValuesButton1:"B1-Two",
          setValuesButton2:"B2-Two",
          setValuesRadio1:true,
          setValuesRadio2:false,
          setValuesRadio3:"one",
          setValuesRadio4:"two",
          setValuesCheckbox1:true,
          setValuesCheckbox2:false
          };
          DWRUtil.setValues(settings);

          DWRUtil.getValues(empty);批量獲取值;
          var empty = {
          setValuesDiv:null,
          setValuesSpan:null,
          setValuesSelect:null,
          setValuesText:null,
          setValuesPassword:null,
          setValuesTextarea:null,
          setValuesButton1:null,
          setValuesButton2:null,
          setValuesRadio1:null,
          setValuesRadio2:null,
          setValuesRadio3:null,
          setValuesRadio4:null,
          setValuesCheckbox1:null,
          setValuesCheckbox2:null
          };
          DWRUtil.getValues(empty);

          DWRUtil.useLoadingMessage("Ping");//類似gmail那個(gè)樣子,在右上角顯示加載"ping";可用自定樣式,具體查詢;
          http://getahead.ltd.uk/dwr/browser/util/useloadingmessage

          DWRUtil.toDescriptiveString("id",數(shù)字);彈出調(diào)試信息,數(shù)字為0,1,2.一級比一級高.

          DWRUtil.onReturn(event, submitFunction);一般在form表單里面,防止在文本框上按回車就提交表單.
          例如:
          <input type="text"
          onkeypress="DWRUtil.onReturn(event, submitFunction)"/>
          <input type="button" onclick="submitFunction()"/>

          posted @ 2007-05-20 12:46 LiuTing 閱讀(616) | 評論 (1)編輯 收藏

          DWR框架實(shí)現(xiàn)Ajax

                Ajax是時(shí)下比較流行的一種web界面設(shè)計(jì)新思路,其核心思想是從瀏覽器獲取XMLHttp對象與服務(wù)器端進(jìn)行交互. DWR(Direct Web Remoting)就是實(shí)現(xiàn)了這種Ajax技術(shù)的一種web框架. 最近做的項(xiàng)目中我也將它用上了,感覺很是方便,比如動(dòng)態(tài)生成javascript代碼,隱藏的http協(xié)議,java代碼和javascript交互的是javascript的對象(或字符串).  下面是我整理的文檔.
            DWR主要由兩部門組成。javascript與web服務(wù)器通信并更新web頁;運(yùn)行在web服務(wù)器的Servlet處理請求并把響應(yīng)發(fā)回瀏覽器。

             1  .  配置web.xml
          <servlet>
            <servlet-name>dwr-invoker</servlet-name>
            <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
          </servlet>
          <servlet-mapping>
            <servlet-name>dwr-invoker</servlet-name>
            <url-pattern>/dwr/*</url-pattern>
          </servlet-mapping>

            2    當(dāng)我們想看dwr自動(dòng)生成的測試頁時(shí),可在java代碼
          servlet中加
          <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
          </init-param>

          這個(gè)參數(shù)DWR默認(rèn)是false.如果選擇true.我們可以通過url http://localhost:port/app/dwr ,你就可以看到你部署的每個(gè)DWR class。并且可以測試java代碼的每個(gè)方法是否運(yùn)行正常。為了安全考慮,在正式環(huán)境下你一定把這個(gè)參數(shù)設(shè)為false.

          3  log信息配置

          我喜歡用log4j輸出日志,那么在log4j.properties下加,log4j.logger.uk.ltd.getahead.dwr = debug。這樣可以看DWR的調(diào)試日志。

          4  配置dwr.xml (和web.xml同目錄)
           
          <create creator="new" javascript="JDate">
          <param name="class" value="java.util.Date"/>
          </create>

          這里的多數(shù)元素都是可選的 - 你真正必須知道的是指定一個(gè)creator和一個(gè)javascript名字。

          creator屬性 是必須的 - 它用來指定使用那種創(chuàng)造器。

          默認(rèn)情況下DWR1.1有8種創(chuàng)造器。它們是:

          • new: 用Java的new關(guān)鍵字創(chuàng)造對象。
          • none: 它不創(chuàng)建對象,看下面的原因。 (v1.1+)
          • scripted: 通過BSF使用腳本語言創(chuàng)建對象,例如BeanShell或Groovy。
          • spring: 通過Spring框架訪問Bean。
          • jsf: 使用JSF的Bean。 (v1.1+)
          • struts: 使用Struts的FormBean。 (v1.1+)
          • pageflow: 訪問Beehive或Weblogic的PageFlow。 (v1.1+)

          javascript屬性 用于指定瀏覽器中這個(gè)被創(chuàng)造出來的對象的名字。你不能使用Javascript的關(guān)鍵字。

          scope屬性 非常類似servlet規(guī)范中的scope。 它允許你指定這個(gè)bean在什么生命范圍。選項(xiàng)有"application", "session", "request" 和"page"。這些值對于Servlet和JSP開發(fā)者來說應(yīng)該相當(dāng)熟悉了。

          scope屬性是可選的。默認(rèn)是"page"。如果要使用"session"需要cookies。當(dāng)前的DWR不支持ULR重寫。

          param元素 被用來指定創(chuàng)造器的其他參數(shù),每種構(gòu)造器各有不同。例如,"new"創(chuàng)造器需要知道要?jiǎng)?chuàng)建的對象類型是什么。每一個(gè)創(chuàng)造器的參數(shù)在各自的文檔中能找到。請查看上面的鏈接。

          include和exclude元素 允許創(chuàng)造器來限制類中方法的訪問。一個(gè)創(chuàng)造器必須指定include列表或exclude列表之一。如果是include列表則暗示默認(rèn)的訪問策略是"拒絕";如果是exclude列表則暗示默認(rèn)的訪問策略是"允許"。


          5 dwr.jar下載后放lib下

          源碼淺析

          dwr的設(shè)計(jì)很象webwork2的設(shè)計(jì),隱藏http協(xié)議,擴(kuò)展性,兼容性及強(qiáng)。

          通過研究uk.ltd.getahead.dwr.DWRServlet這個(gè)servlet來研究下dwr到底是如何工作的。

          <servlet>
            <servlet-name>dwr-invoker</servlet-name>
            <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
          </servlet>
          <servlet-mapping>
            <servlet-name>dwr-invoker</servlet-name>
            <url-pattern>/dwr/*</url-pattern>
          </servlet-mapping>

          這樣/dwr/*下的所有的請求都是由這個(gè)servlet來處理,到底生理了什么呢,我們還是以例子來說明吧.

          1 web服務(wù)器啟動(dòng),DWRServlet init()方法調(diào)用,init主要做了以下工作。
          設(shè)置日志級別、實(shí)例化DWR用到的單例類(這些類在jvm中只有一個(gè)實(shí)例對象)、讀去配置文件(包括dwr.jar包中的dwr.xml,WEB-INF/dwr.xml. config*.xml)。
          2 請求處理
          DWRServlet.doGet, doPost方法都調(diào)用processor.handle(req, resp)方法處理。Processor對象在init()方法中已經(jīng)初始化了。 

          代碼
          public void handle(HttpServletRequest req, HttpServletResponse resp)  
                  throws IOException  
              {  
                  String pathinfo = req.getPathInfo();  
                  if(pathinfo == null || pathinfo.length() == 0 || pathinfo.equals("/"))  
                  {  
                      resp.sendRedirect(req.getContextPath() + req.getServletPath() + '/' + "index.html");  
                  } else 
                  if(pathinfo != null && pathinfo.equalsIgnoreCase("/index.html"))  
                  {  
                      doIndex(req, resp);  
                  } else 
                  if(pathinfo != null && pathinfo.startsWith("/test/"))  
                  {  
                      doTest(req, resp);  
                  } else 
                  if(pathinfo != null && pathinfo.equalsIgnoreCase("/engine.js"))  
                  {  
                      doFile(resp, "engine.js", "text/javascript");  
                  } else 
                  if(pathinfo != null && pathinfo.equalsIgnoreCase("/util.js"))  
                  {  
                      doFile(resp, "util.js", "text/javascript");  
                  } else 
                  if(pathinfo != null && pathinfo.equalsIgnoreCase("/deprecated.js"))  
                  {  
                      doFile(resp, "deprecated.js", "text/javascript");  
                  } else 
                  if(pathinfo != null && pathinfo.startsWith("/interface/"))  
                  {  
                      doInterface(req, resp);  
                  } else 
                  if(pathinfo != null && pathinfo.startsWith("/exec"))  
                  {  
                      doExec(req, resp);  
                  } else 
                  {  
                      log.warn("Page not found. In debug/test mode try viewing /[WEB-APP]/dwr/");  
                      resp.sendError(404);  
                  }  
              } 

          dwr/*處理的請求也就這幾種。

          (1)dwr/index.html,dwr/test/這種只能在debug模式下使用,調(diào)試用。
          dwr/engine.js,dwr/util.js,dwr/deprecated.js當(dāng)這個(gè)請求到達(dá),從dwr.jar包中讀取文件流,響應(yīng)回去。(重復(fù)請求有緩存)
          (2)當(dāng)dwr/interface/這種請求到來,(例如我們在index.html中的 <script type='text/javascript' src='dwr/interface/JDate.js'></script>)DWR做一件偉大的事。把我們在WEB-INF/dwr.xml中的
          <create creator="new" javascript="JDate">
          <param name="class" value="java.util.Date"/>
          </create>
          java.util.Date轉(zhuǎn)化為javascript函數(shù)。
          http://localhost:port/simpledwr/dwr/interface/JDate.js看看吧。
          細(xì)節(jié)也比較簡單,通過java反射,把方法都寫成javascript特定的方法。(我覺得這些轉(zhuǎn)換可以放到緩存里,下次調(diào)用沒必要再生成一遍,不知道作者為什么沒這樣做)。
          (3)dwr/exec
          javascript調(diào)用方法時(shí)發(fā)送這種請求,可能是XMLHttpRequest或IFrame發(fā)送。
          當(dāng)然,javascript調(diào)用的方法簽名與java代碼一致,包括參數(shù),還有javascript的回調(diào)方法也傳到了服務(wù)器端,在服務(wù)器端很容易實(shí)現(xiàn)。回調(diào)方法的java的執(zhí)行結(jié)果 返回類似 <script>callMethod(結(jié)果)<script>的javascript字符串,在瀏覽器執(zhí)行。哈,一切就這么簡單,巧妙。

          我這里還有DWR中文文檔. http://www.aygfsteel.com/Files/LiuTing/DWR中文文檔.rar





          posted @ 2007-05-20 12:45 LiuTing 閱讀(4340) | 評論 (4)編輯 收藏

          Acegi工作流程

          任何一個(gè)安全系統(tǒng)都包括authentication和authorization兩部分,Acegi相同。

          第一部分:authentication

          1、acegi通過AuthenticationProcessingFilter攔截login請求獲取Principal和Credential信息(通俗一點(diǎn)就是用戶名和密碼);

          2、驗(yàn)證用戶名密碼,由這個(gè)Filter調(diào)用認(rèn)證管理器AuthenticatiomManager進(jìn)行驗(yàn)證。

          AuthenticatiomManager本身并不具備驗(yàn)證的功能,它相當(dāng)與是一個(gè)驗(yàn)證控制器,由它來管理驗(yàn)證的過程及方式。AuthenticatiomManager是通過調(diào)用provider來進(jìn)行驗(yàn)證的,一個(gè)manager中可以具有多個(gè)provider,但只要有一個(gè)provider驗(yàn)證通過,manager就認(rèn)為驗(yàn)證成功。

          這部分要明白三點(diǎn):一,provider是可以配置進(jìn)去的,因?yàn)閍cegi是基于spring的;二是AuthenticatiomManager是可以被重寫的,你可以將manager改成你自己希望的控制器;三,好好利用event,這是標(biāo)準(zhǔn)的observer模式。acegi中的設(shè)計(jì)模式研究將在以后的貼子中討論。

          3、provider進(jìn)行驗(yàn)證。

          provider是真正的驗(yàn)證模塊,并且決定了驗(yàn)證的模式。provider目前acegi提供了dao、jaas,cas,x509,ldap等幾種驗(yàn)證方式,這些驗(yàn)證方式的具體內(nèi)容可以查閱acegi的文檔。provider驗(yàn)證通過后將Authentication對象返回。

          4、AuthenticationProcessingFilter將對象保存到ContextHolder中。Authentication部分結(jié)束。

          第二部分:authorization

          1、用戶提交請求,攔截器FilterSecurityInterceptor攔截請求,攔截器是一個(gè)Filter.

          2 、鑒權(quán),攔截器調(diào)用AccessDecisionManager進(jìn)行鑒權(quán)。

          AccessDecisionManager是通過投票的方式來決定是否有權(quán)限訪問資源。所謂投票就要包括投票的參與者和投票的策略。

          投票的參與者decisionVoters,這是AccessDecisionManager的一個(gè)屬性。decisionVoter能從某一個(gè)角度決定用戶是否能訪問資源,例如RoleVoter來判斷用戶的角色是否有權(quán)限訪問資源,MaxuserVoter來決定某個(gè)資源的訪問用戶數(shù)是否已經(jīng)達(dá)到了最大值等。

          投票策略。投票的策略是通過不同的AccessDecisionManager來實(shí)現(xiàn)的,例如acegi提供的AffirmativeBased對象,這個(gè)對象的策略就是只要有一個(gè)投票通過就全體通過。UnanimousBased對象的策略是必須全體投票通過才能通過。但在大多數(shù)情況下acegi提供的AccessDecisionManager不能滿足我們的要求,這就需要我們?nèi)?shí)現(xiàn)AccessDecisionManager接口,去定制適合自己項(xiàng)目的策略。

          3、投票。投票對象必須實(shí)現(xiàn)AccessDecisionVoter接口。投票對象關(guān)注的是某一方面的決定權(quán),如果投票通過則Vote方法來完成的。vote方法必須返回一個(gè)int型的數(shù)據(jù)代表投票結(jié)果,它們是AccessDecisionVoter的三個(gè)靜態(tài)成員屬性:ACCESS_ABSTAIN,,ACCESS_DENIED和ACCESS_GRANTED,它們分別是棄權(quán),否決和贊成。
           

          安全攔截器

            攔截器如何工作
            MethodInvocation攔截器
            FilterInvocation攔截器

          認(rèn)證

            認(rèn)證請求
            認(rèn)證管理器
            Authentication Provider

          授權(quán)

            Access Decision Manager
            Voting Decision Manager
            授權(quán)管理推薦

          ContextHolder的用戶接口

            用戶接口目標(biāo)
            HTTP會(huì)話認(rèn)證
            HTTP Basic認(rèn)證

          posted @ 2007-05-20 12:44 LiuTing 閱讀(650) | 評論 (1)編輯 收藏

          使用Acegi時(shí)獲取用戶信息的幾個(gè)函數(shù)

          1 /**
           2    * 取得當(dāng)前用戶名
           3    *  @return
           4     */

           5    public   static  String getUsername() {
           6     Context context = ContextHolder.getContext();
           7      if (context != null ) {
           8        if (context  instanceof  SecureContext) {
           9         SecureContext sc = (SecureContext)context;
          10         Authentication auth = sc.getAuthentication();
          11          if (auth != null ) {
          12           Object principal = auth.getPrincipal();
          13            if (principal  instanceof  UserDetails)  {
          14              return  ((UserDetails)principal).getUsername();
          15           }
          else {
          16              return  principal.toString();
          17           }

          18         }

          19       }

          20     }

          21      return   null ;
          22   }

          23    /**
          24    * 取得當(dāng)前用戶密碼
          25    *  @return
          26     */

          27    public   static  String getPassword() {
          28     Context context = ContextHolder.getContext();
          29      if (context != null ) {
          30        if (context  instanceof  SecureContext) {
          31         SecureContext sc = (SecureContext)context;
          32         Authentication auth = sc.getAuthentication();
          33          if (auth != null ) {
          34           Object principal = auth.getPrincipal();
          35            if (principal  instanceof  UserDetails)  {
          36              return  ((UserDetails)principal).getPassword();
          37           }
          else {
          38              return   null ;
          39           }

          40         }

          41       }

          42     }

          43      return   null ;
          44   }

          45    /**   */ /**
          46    * 取得當(dāng)前用戶session id
          47    *  @return  sessionid or null
          48     */

          49    public   static  String getSessionID() {
          50     Context context = ContextHolder.getContext();
          51      if (context != null ) {
          52        if (context  instanceof  SecureContext) {
          53         SecureContext sc = (SecureContext)context;
          54         Authentication auth = sc.getAuthentication();
          55          if (auth != null ) {
          56           Object details = auth.getDetails();
          57            if (details  instanceof  WebAuthenticationDetails)  {
          58              return  ((WebAuthenticationDetails)details).getSessionId();
          59           }
          else {
          60              return   null ;
          61           }

          62         }

          63       }

          64     }

          65      return   null ;
          66   }

          posted @ 2007-05-20 12:43 LiuTing 閱讀(368) | 評論 (0)編輯 收藏

          Acegi使用2

          流程說完了,接下對上面提到的問題解釋一下:

          引用

          先使用URL攔截的方式去對付大多數(shù)的情況,然后少數(shù)URL搞不定的再加一個(gè)接口,讓Action自己去判別。這樣用兩個(gè)攔截器對Action進(jìn)行攔截,如果Action實(shí)現(xiàn)了hasPermission接口,那么就交給Action自己判斷,如果Action沒有該接口,就查找內(nèi)部的URL和權(quán)限的對照表來判斷。

           

          這個(gè)情況比較復(fù)雜,因?yàn)槭且獙ction進(jìn)行調(diào)用,所以要看使用的web框架來定奪。是用不同Web框架要是用不同的Web框架攔截器。所以恐怕acegi力不從心,挺多在filter里面配置一下是否要是用Action自身校驗(yàn)。但是想法很好,贊。

           

          引用

          你怎么把信息有效的傳遞給Web層和其他的Facade層進(jìn)行用戶友好性的提示處理?

           

          acegi校驗(yàn)失敗的時(shí)候會(huì)拋出AuthenticationException異常,然后放在session里面,
          在錯(cuò)誤轉(zhuǎn)向頁面可以這樣是用

          代碼
          <%= ((AuthenticationException) session.getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY)).getMessage() %>    
          <%= session.getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY) %>    
          <%= session.getAttribute(SecurityEnforcementFilter.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY) %> 

          不過這么用實(shí)在太難看了,暈了。可以自己用tag來搞定

           

           

          引用

          很多系統(tǒng)需要根據(jù)權(quán)限不同,生成不同的UI組件(例如管理員的菜單和普通用戶菜單就肯定不一樣),這也需要在Web層的View進(jìn)行控制。

          acegi對View的處理就是使用tag,原來的acegi好像沒有什么tag,簡直是爛,現(xiàn)在有了tag,說一下是用的方法,但是說實(shí)話他的tag實(shí)在是不夠強(qiáng)。

           

          老版的web.xml

          代碼
          1<taglib>   
          2  <taglib-uri>http://acegisecurity.sf.net/authz</taglib-uri>   
          3  <taglib-location>/WEB-INF/authz.tld</taglib-location>   
          4</taglib>  

          在頁面中使用
          代碼
          1<authz:authorize ifAllGranted="ROLE_SUPERVISOR">   
          2<td>   
          3<HREF="del.htm?id=<c:out value="/${contact.id}"/>">Del</A>   
          4</td>   
          5</authz:authorize>  

          ifAllGranted是說所有的權(quán)限都有,用','分割權(quán)限
          可以替換成ifAnyGranted: ifNotGranted:

           

           

          代碼
          1<authz:authentication operation="username"/>   

           

          這個(gè)是用來顯示你的權(quán)限信息的。

           

          代碼
          1<authz:acl domainObject="${contact}" hasPermission="16,1">   
          2<td><HREF="<c:url value="del.htm"><c:param name="contactId"   
          3value="${contact.id}"/></c:url>">Del</A></td>   
          4</authz:acl>  

          posted @ 2007-05-20 12:42 LiuTing 閱讀(496) | 評論 (0)編輯 收藏

          Acegi使用1

          首先要配置一個(gè)filter,這個(gè)filter用一個(gè)代理bean寫在了spring里面,其實(shí)根正常的filter沒有任何區(qū)別。

          代碼
          1<bean id="securityEnforcementFilter"   
          2    class="org.acegisecurity.intercept.web.SecurityEnforcementFilter">   
          3    <property name="filterSecurityInterceptor">   
          4        <ref local="filterInvocationInterceptor" />   
          5    </property>   
          6    <property name="authenticationEntryPoint">   
          7        <ref local="authenticationProcessingFilterEntryPoint" />   
          8    </property>   
          9</bean>  

           

          "filterInvocationInterceptor" 是一個(gè)攔截器,說是攔截器,其實(shí)就是在filter里面執(zhí)行一下他的攔截方法,這里可沒有什么aop.
          authenticationEntryPoint 交驗(yàn)失敗的時(shí)候轉(zhuǎn)到的地方,為什么說是地方,因?yàn)橥ㄟ^配置可以轉(zhuǎn)到其它的url甚至其它的協(xié)議下(http 轉(zhuǎn)到 https等等)
           
          代碼
           1<bean id="authenticationProcessingFilterEntryPoint"   
           2    class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">   
           3    <property name="loginFormUrl">   
           4        <value>/error.security</value>   
           5    </property>   
           6    <property name="forceHttps">   
           7        <value>false</value>   
           8    </property>   
           9</bean>  
          10

           

          這個(gè)就是失敗的時(shí)候轉(zhuǎn)到的地方,我們可以配置url和是否使用https

           

          代碼
           1<bean id="filterInvocationInterceptor"   
           2    class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">   
           3    <property name="authenticationManager">   
           4        <ref bean="authenticationManager" />   
           5    </property>   
           6    <property name="accessDecisionManager">   
           7        <ref local="httpRequestAccessDecisionManager" />   
           8    </property>   
           9    <property name="objectDefinitionSource">   
          10        <value>   
          11            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON    
          12            PATTERN_TYPE_APACHE_ANT    
          13            /index.jsp=ROLE_ANONYMOUS,ROLE_USER    
          14            /j_acegi_switch_user=ROLE_SUPERVISOR   
          15            /login.security=ROLE_ANONYMOUS,ROLE_USER                /test.do=ROLE_CODER   
          16            /**.do*=ROLE_USER    
          17        </value>   
          18    </property>   
          19</bean>  

           

          這個(gè)就是前面提到的攔截器。簡單解釋一下:
          authenticationManager 在acegi里面的主要作用就是管理維護(hù)用戶的權(quán)限角色等信息,比方說想要用戶的ROLE就要在這里面拿了。里面配置了多種全縣的來源,可以從DAO里面來(就是數(shù)據(jù)庫里面),可以是cookies里面的,也可以是匿名的權(quán)限,每種權(quán)限都以一種Provider的形式提供:

          代碼
           1<bean id="authenticationManager"   
           2    class="org.acegisecurity.providers.ProviderManager">   
           3    <property name="providers">   
           4        <list>   
           5            <ref local="daoAuthenticationProvider" />   
           6            <ref local="anonymousAuthenticationProvider" />   
           7            <ref local="rememberMeAuthenticationProvider" />   
           8        </list>   
           9    </property>   
          10</bean>

           

          objectDefinitionSource在acegi里面就是配置權(quán)限信息,說明哪一個(gè)url需要什么權(quán)限才能訪問,acegi默認(rèn)用<value>來表示,其實(shí)這正是acegi的不足之處,還好能夠補(bǔ)救。我來說明一下:
          我們知道在spring里面<value>標(biāo)簽比較特殊,spring首先找到這個(gè)屬性的類型,然后把value里面的內(nèi)容以String的類型取出來(Spring做了一下包裝,為TypedString)。然后根據(jù)這個(gè)屬性的類型找他的Editer,然后用Editer來處理String為需要的類型。但是我們不希望用String來表達(dá)url,很明顯url里面有=就不會(huì)玩了。我們可以把這個(gè)信息寫到數(shù)據(jù)庫里面,然后讀取,這里面不說了以前有一位高手已經(jīng)解釋過了。

          接下來就是httpRequestAccessDecisionManager了,AccessDecisionManager在acegi里面是決策者,就是根據(jù)你所擁有的權(quán)限和訪問URL需要的權(quán)限來決定你到底能不能訪問。

           

          代碼
           1<bean id="httpRequestAccessDecisionManager"   
           2    class="org.acegisecurity.vote.AffirmativeBased">   
           3    <property name="allowIfAllAbstainDecisions">   
           4        <value>false</value>   
           5    </property>   
           6    <property name="decisionVoters">   
           7        <list>   
           8            <ref bean="roleVoter" />   
           9        </list>   
          10    </property>   
          11</bean>  

           

          決策者里面是投票者,這個(gè)上面已經(jīng)解釋過了,一個(gè)投票者校驗(yàn)一種權(quán)限。整個(gè)流程已經(jīng)說完了。

          posted @ 2007-05-20 12:41 LiuTing 閱讀(408) | 評論 (0)編輯 收藏

          Eclipse報(bào)表插件birt

           

          1. BIRT 概述

          BIRT是一個(gè)Eclipse-based開放源代碼報(bào)表系統(tǒng)。它主要是用在基于JavaJ2EEWeb應(yīng)用程序上。BIRT主要由兩部分組成:一個(gè)是基于Eclipse的報(bào)表設(shè)計(jì)和一個(gè)可以加到你應(yīng)用服務(wù)的運(yùn)行期組件。BIRT同時(shí)也提供一個(gè)圖形報(bào)表制作引擎。

              使用BIRT,能制作出多樣化的報(bào)表到你的應(yīng)用中。比如:列表 lists ,圖表 charts,混合報(bào)表 Compound Reports,交叉表(二維表)Crosstabs(二維報(bào)表目前在BIRT 2.1.1 還未實(shí)現(xiàn),但在以后的版本中將會(huì)實(shí)現(xiàn)此功能)。

          2. BIRT的安裝

          2.1>birt的安裝

          Eclipse 3.1
          支持 BIRT 2.0

          Eclipse 3.2 支持 BIRT 2.1

           

          目前我使用的版本是BIRT 2.1.1BIRT的安裝有很多的方法。

          方法一:

          Eclipse的官方網(wǎng)站http://download.eclipse.org/birt/downloads去下載 BIRT 插件(birt-report-designer-all-in-one-2_1_1),解壓后,它就是一個(gè)擁有 BIRT插件的Eclipse。如果你已經(jīng)安裝了Eclipse,那么把下載的文件夾的內(nèi)容拷到所對應(yīng)的 Eclipse 的文件夾里(pluginsfeatures兩個(gè)目錄),之后的第一次啟動(dòng)是通過DOS進(jìn)入到Eclipse目錄,啟動(dòng) Eclipse -clean 命令,此命令是清除 Eclipse 緩存里的記錄并啟動(dòng)Eclipse。這也是最簡單的安裝BIRT方法。

           

          方法二:

              BIRT 2.1開始,可以在 Eclipse 里直接下載。[幫助]à[軟件更新]à[查找并安裝]

           

          方法三:

              如果你的 Eclipse 已經(jīng)安裝或者不想使用方法一安裝,可以進(jìn)行分別安裝的方法。EMF, GEF BIRT 都是需要通過 Eclipse download page下載的。請注意以下的配置要求:

          • BIRT 2.0.2
          • Eclipse 3.1
          • GEF 3.1.
          • EMF 2.1.
          • JRE 1.4.2/JRE 1.5.
          • BIRT 2.1/2.1.1
          • Eclipse 3.2.
          • GEF 3.2.
          • EMF 2.2.
          • JRE 1.4.2/JRE 1.5.
          • BIRT 2.2M4 and higher
          • Eclipse 3.3.
          • GEF 3.3.
          • EMF 2.3.
          • JRE 1.5.

          GEF:圖形編輯框架,是一個(gè)通過 BIRT UI 使用的Eclipse 插件

          EMF:用來制作圖表的框架

          具體的安裝和配置請參考 Eclipse官方網(wǎng)站 這里我還推薦一個(gè)BIRT 2.0.1的安裝視頻 希望對大家有所幫助。

          注意:iTextAsian.jar 是為了支持用PDF輸出時(shí)亞洲人的字體。prototype.js 是安裝 BIRT 2.0.2 或者更早的版本使用的,目前版本不需要了。

          提示:我個(gè)人使用的是方法一,首先安裝比較方便,其次如果使用方法二,在Eclipse [幫助]à[幫助內(nèi)容] 里沒有關(guān)于 BIRT 的幫助文檔,這樣對學(xué)習(xí)不是很方便。

           2.2    birt版本升級

          1.刪除在 plugins 目錄下的所有以 org.eclipse.birt 開頭的文件。

          2.
          按照上面的方法一進(jìn)行安裝。

          3.重新啟動(dòng) Eclipse -clean

           2.3  語言包安裝

              目前 BIRT2.1.1 已經(jīng)有中文語言包。下載完畢以后把對應(yīng)的目錄 copy 到對應(yīng)的 Eclipse 目錄下,然后 Eclipse -clean 啟動(dòng)。

            

          3. BIRT應(yīng)用

              在這里我提供了一個(gè) “BIRT中文教程”,在Eclipse官方網(wǎng)站也有它的演示視頻,Customers.rptdesign 是做好的報(bào)表。

           

          JDBC Drivers

              以上例子介紹的是使用“示例數(shù)據(jù)庫”的數(shù)據(jù)源,在大多數(shù)情況下我們使用的是自己的JDBC driver,下面介紹連接 Oracle 數(shù)據(jù)庫。

              打開 Eclipse 后進(jìn)入 [窗口]à[打開透視圖]à[報(bào)表設(shè)計(jì)],新建項(xiàng)目 [文件]à[新建]à[項(xiàng)目],選擇“業(yè)務(wù)智能和報(bào)表工具”à“報(bào)表項(xiàng)目”,起項(xiàng)目名。新建的項(xiàng)目上,右鍵 新建報(bào)表,給報(bào)表起名字,報(bào)表的后綴名是 .rptdesign

              [數(shù)據(jù)源]à[新建數(shù)據(jù)源],選擇“JDBC數(shù)據(jù)源”(別忘了給數(shù)據(jù)源起名字),“管理驅(qū)動(dòng)程序”à“添加”,把所需要的數(shù)據(jù)庫 jar 包添加進(jìn)來。選擇oracle.jdbc.driver.OracleDriver ( v1.0),寫上正確的數(shù)據(jù)庫 URL,用戶名,密碼,點(diǎn)擊“測試連接”,顯示 連接成功。

           

          報(bào)表的種類有很多,具體的制作過程參考[幫助]à[幫助內(nèi)容]

           

          提示:交叉表即二維報(bào)表在目前BIRT 2.1.1 還未實(shí)現(xiàn),但在以后的版本中正在計(jì)劃實(shí)現(xiàn)此功能。

           

          4. BIRT部署

          BIRT 2.1.1所對應(yīng)使用的部署工具是birt-runtime-2_1_1,可以到 Eclipse 官方網(wǎng)站下載。

           
          4.1. tomcat 部署

          我使用的版本是 tomcat 5.5,步驟如下:

          1)      mail.jar activation.jar拷到Tomcat 5.5\common\lib

          2)      iTextAsian.jar itext-1.3.jar拷到

          WebViewerExample\WEB-INF\platform\plugins\com.lowagie.itext\lib

          3)      連接數(shù)據(jù)庫的包拷到

          WebViewerExample\WEB-INF\platform\plugins\org.eclipse.birt.report.data.oda.jdbc_2.1.1.v20060922-1058\drivers

          4)      WebViewerExample整個(gè)目錄copy Tomcat 5.5\webapps,可以更改文件夾名。

          5)      完成的報(bào)表可以直接復(fù)制到根目錄下,也可以新建文件夾目錄。

           

          現(xiàn)在BIRT支持兩種瀏覽報(bào)表模式,frameset是支持顯示分頁的,采用Ajax技術(shù)。run暫不支持顯示分頁,直接輸出HTML流。比較一下它們的區(qū)別,如下:

          http://localhost:8080/WebViewerExample/frameset?__report=Customers.rptdesign

          http://localhost:8080/WebViewerExample/run?__report=Customers.rptdesign

          注意:

          a)      問號后面的是雙下劃線

          b)      以上報(bào)表是放在根目錄下,如果是放在自己新建的目錄比如 myreport URL應(yīng)是:

          http://localhost:8080/WebViewerExample/run?__report=myreport/Customers.rptdesign

           
          4.2. Weblogic Server 部署

          我使用的版本是 Weblogic Server 9.2,它是 BEA WebLogic 產(chǎn)品的一部分。BEA WebLogic Server 是一個(gè)功能豐富、基于標(biāo)準(zhǔn)的現(xiàn)成的企業(yè) J2EE應(yīng)用服務(wù)器。

          Weblogic Server 有很多的域組成,medrec wl_server 是其中自帶的域,也可以自己創(chuàng)建新的域。域中可以包含許多服務(wù)器,在服務(wù)器中可以部署許多的應(yīng)用程序。域有一個(gè)默認(rèn)的服務(wù)器,它是管理服務(wù)器。每個(gè)域中的管理服務(wù)器是唯一的,其他創(chuàng)建的服務(wù)器叫受管服務(wù)器。

          Weblogic Server 的安裝就不多做介紹了,主要介紹它的配置和部署。下面介紹一下新建域和部署的步驟:

          1)      運(yùn)行開始 -> 程序 -> BEA Products -> Tools -> Configuration Wizard

          2)      選擇 Create a new WebLogic domainNext

          3)      Select Domain Source 界面保持默認(rèn),Next

          4)      User name 處輸入用戶名,如 userpassword 輸入密碼,如12345678(密碼要求 8 位),Next

          5)      Configure Server Start Mode and JDK 界面中保持默認(rèn),即 JDK 選擇的是“Sun SDK 1.5.0_04 @ C:\BEA\jdk150_04,注意這里若選擇“Other JDK”配置比 SDK 1.5.0_04 更高的版本,服務(wù)器啟動(dòng)時(shí)將會(huì)出現(xiàn)異常,所以最好保持默認(rèn),然后 Next

          6)      Customize Environment and Services Settings 界面中默認(rèn)為 NoNext

          7)      Domain name 處輸入 mydomain,點(diǎn)擊 Create

          8)      完成后點(diǎn)擊 Done 關(guān)閉 Configuration Wizard 對話框。

          9)      運(yùn)行開始 -> 程序 -> BEA Products -> User Projects -> mydomain -> Start Admin Server for Weblogic Server Domain,啟動(dòng)創(chuàng)建域的服務(wù)器。如果最后顯示 <Server started in RUNNING mode> 則說明服務(wù)器啟動(dòng)成功。

          10) 在地址欄輸入 http://localhost:7001/console 進(jìn)入管理控制臺,輸入剛才的用戶名和密碼。點(diǎn)擊 更改中心 的[鎖定并編輯],域結(jié)構(gòu) 中的[部署],點(diǎn)擊[安裝]。找到你要部署的應(yīng)用程序,之后都為默認(rèn),最后點(diǎn)完成。在更改頁面上點(diǎn)擊[保存]完成所需的更改后,單擊 更改中心 中的[激活更改]注意:只有點(diǎn)擊了[激活更改]后才真正保存了更改。某些在管理控制臺中所做的更改在激活后立即生效。有些更改需要重新啟動(dòng)此更改影響到的服務(wù)器或模塊。后面的這些更改稱為非動(dòng)態(tài)更改。非動(dòng)態(tài)更改在管理控制臺中由此警告圖標(biāo)表示: 如果對非動(dòng)態(tài)配置設(shè)置進(jìn)行了編輯,則只有在重新啟動(dòng)服務(wù)器之后,所有對動(dòng)態(tài)配置設(shè)置所進(jìn)行的編輯才會(huì)生效。

          11) 點(diǎn)擊 域結(jié)構(gòu) 中的[部署],啟動(dòng)剛才部署的應(yīng)用程序。

          12) 在地址欄中輸入 http://localhost:7001/部署程序名在web中顯示應(yīng)用程序。

           

              BIRT的部署方法基本和上面步驟相同,注意一點(diǎn),在部署前將

          commons-logging.jar 拷入 WebViewerExample 中的 lib 包中,否則最后顯示會(huì)報(bào)錯(cuò)。

           

              Weblogic Server 的部署方法有很多,weblogic.Deployer、管理控制臺、WLST 等等。剛才介紹的管理控制臺的部署,它是一個(gè)可視化的界面,用起來比較方便。

           

          推薦:在這里推薦使用一種應(yīng)用程序的目錄管理方法,新建目錄結(jié)構(gòu)如下:

          C:myApplication

          app

          plan

          將你的應(yīng)用程序放入此目錄

          部署完后將會(huì)再此目錄下自動(dòng)產(chǎn)生plan.xml文件

          用此目錄有利于很好的管理配置文件。

           

          關(guān)于 Weblogic 的更多詳細(xì)資料,我這里推薦幾個(gè)比較好的官方學(xué)習(xí)網(wǎng)站:

          www.bea.com.cn          bea的產(chǎn)品網(wǎng)站

          edocs.bea.com.cn       bea的比較系統(tǒng)的學(xué)習(xí)網(wǎng)站

          dev2dev.bea.com.cn      一般介紹bea的最新技術(shù),動(dòng)態(tài)等的網(wǎng)站
           
          4.3. web外觀顯示

              部署好的報(bào)表頁面顯示樣式是固定的,在多數(shù)情況下我們都希望修改外觀,下面將對此做簡單介紹。

          Webcontent是主要文件夾:

          1)      Webcontent中的ajax目錄,完成了在web上顯示的報(bào)表分頁的功能。

          2)      Styles目錄中的style.css是整個(gè)報(bào)表在web上顯示的外觀,包括工具條顏色,字體。文件注釋很清楚,具體修改可以參見注釋。

          3)      pages目錄pages/control/ NavigationbarFragment.jsp 分頁那一條工具欄的 JSP pages/control/ ToolbarFragment.jsp 工具按紐JSP,可以修改以保留自己想要使用的功能按紐。pages/control/ ProgressBarFragment.jsp 它是顯示剛開始讀取報(bào)表時(shí),顯示條的樣式。

          4)      Layout目錄 FramesetFragment.jsp 可以修改報(bào)表標(biāo)題。

           

          WEB-INF/web.xml文件中,BIRT_VIEW_REPORT_ROOT 是配置報(bào)表路徑的屬性,如果沒有配置則是默認(rèn)路徑:$tomcat$\webapps\birt

              目前在web上顯示的所有的都是英文。項(xiàng)目有一個(gè)資源文件,打包在lib/viewservlets.jar中,…/…/resource/messages.properties文件中。顯示中文的解決方法是,用unicode轉(zhuǎn)換器把要顯示的中文事先轉(zhuǎn)換好,然后替換資源文件中的英文。

           

          5. BIRT總結(jié)

          BIRT是目前比較常用也是比較方便,效率較高的報(bào)表制作工具。當(dāng)然其發(fā)展時(shí)間不長,所以還有很多的缺陷和未完善的地方,之后的版本也在不斷改進(jìn),因此我也將會(huì)一直跟蹤它的技術(shù)發(fā)展,不斷更新我的文檔。

          posted @ 2007-05-20 12:40 LiuTing 閱讀(4586) | 評論 (1)編輯 收藏

          主站蜘蛛池模板: 东阿县| 云梦县| 云龙县| 尉氏县| 宜丰县| 元江| 瓮安县| 景宁| 项城市| 临高县| 甘德县| 深泽县| 温州市| 莱阳市| 古蔺县| 武城县| 长沙县| 隆子县| 新野县| 尚志市| 广西| 博白县| 铜陵市| 河间市| 富民县| 曲松县| 尤溪县| 尖扎县| 确山县| 木里| 荔波县| 阿拉善左旗| 江川县| 抚州市| 甘孜| 涞水县| 扎鲁特旗| 潢川县| 新郑市| 台东县| 五家渠市|