posts - 10, comments - 9, trackbacks - 0, articles - 17

          2009年4月21日

          選自 http://java.chinaitlab.com/Spring/762022.html

           Spring Security使用一組過濾器鏈來對用戶進行身份驗證和授權。首先,在web.xml文件中添加FilterToBeanProxy過濾器配置:
           1 <filter>   
           2       <filter-name>springSecurityFilterChain</filter-name>
           3      <filter-class>
           4         org.springframework.security.util.FilterToBeanProxy
           5      </filter-class>
           6      <init-param>       
           7           <
          param-name>targetClass</param-name>
           8          <param-value>           
           9               org.springframework.security.util.FilterChainProxy
          10          </param-value>
          11       </init-param>
          12 </filter>
          13
                  org.springframework.security.util.FilterToBeanProxy實現了Filter接口,它通過調用WebapplicationContextUtils類的getWebApplicationnContext(servletContext)方法來獲取Spring的應用上下文句柄,并通過getBean(beanName)方法來獲取Spring受管Bean的對象,即這里targetClass參數配置的Bean,并通過調用FilterChain Proxy的init()方法來啟動Spring Security過濾器鏈進行各種身份驗證和授權服務(FilterChainProxy類也是實現了Filter接口),從而將過濾功能委托給Spring的FilterChainProxy受管Bean(它維護著一個處理驗證和授權的過濾器列表,列表中的過濾器按照一定的順序執行并完成認證過程),這樣即簡化了web.xml文件的配置,又能充分利用 Spring的IoC功能來完成這些過濾器執行所需要的其它資源的注入。

                  當用戶發出請求,過濾器需要根據web.xml配置的請求映射地址來攔截用戶請求,這時Spring Security開始工作,它會驗證你的身份以及當前請求的資源是否與你擁有的權限相符,從而達到保護Web資源的功能,下面是本例所要過濾的用戶請求地址:
           1 <filter-mapping>
           2 
           3        <filter-name>springSecurityFilterChain</filter-name>

           5        <url-pattern>/j_spring_security_check</url-pattern>
           6 
           7     </filter-mapping>
           8 
           9     <filter-mapping>
          10 
          11        <filter-name>springSecurityFilterChain</filter-name>
          12 
          13        <url-pattern>/*</url-pattern>
          14 
          15 </filter-mapping>

          提示:
          /j_spring_security_check是Spring Security默認的進行表單驗證的過濾地址,你也可以修改為別的名稱,但是需要和
          applicationContext-security.xml中相對應,當然還會涉及到其它一些默認值(可能是一個成員變量,也可能是別的請
          求地址),在下文我們將看到,建議你在閱讀此文的同時,應該參照Spring Security項目的源代碼,便于你更好的理解。


          3 配置applicationContext-security.xml

              3.1 FilterChainProxy過濾器鏈

              FilterChainProxy會按順序來調用一組filter,使這些filter即能完成驗證授權的本質工作,又能享用Spring Ioc的功能來方便的得到其它依賴的資源。FilterChainProxy配置如下:

           1 <bean id="filterChainProxy"   
                  class
          ="org.springframework.security.util.FilterChainProxy">
           2      <property name="filterInvocationDefinitionSource">
           3         <value><![CDATA[         
                          CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 
           4              PATTERN_TYPE_APACHE_ANT         
                          /**=httpSessionContextIntegrationFilter,logoutFilter,
           5              authenticationProcessingFilter,securityContextHolderAwareRequestFilter,
           6              rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,
           7              filterSecurityInterceptor 
           8         ]]></value>
           9      </property>
          10 </bean>

              CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 定義URL在匹配之前必須先轉為小寫,PATTERN_TYPE_APACHE_ANT 定義了使用Apache ant的匹配模式,/**定義的將等號后面的過濾器應用在那些URL上,這里使用全部URL過濾,每個過濾器之間都適用逗號分隔,它們按照一定的順序排列。

           
          提示:
          特別需要注意的是,即使你配置了系統提供的所有過濾器,這個過濾器鏈會很長,但是千萬不要使用換行,否則它們不會正常工作,
          容器甚至不能正常啟動。
           

              下面根據FilterChainProxy的配置來介紹各個過濾器的配置,各個過濾器的執行順序如以上配置。

              首先是通道處理過濾器,如果你需要使用HTTPS,這里我們就使用HTTP進行傳輸,所以不需要配置通道處理過濾器,然后是集成過濾器,配置如下:

          1 <bean id="httpSessionContextIntegrationFilter"
          2 
          3 class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>

              httpSessionContextIntegrationFilter是集成過濾器的一個實現,在用戶的一個請求過程中,用戶的認證信息通過SecurityContextHolder(使用ThreadLoacl實現)進行傳遞的,所有的過濾器都是通過SecurityContextHolder來獲取用戶的認證信息,從而在一次請求中所有過濾器都能共享Authentication(認證),減少了HttpRequest參數的傳送,下面的代碼是從安全上下文的獲取Authentication對象的方法:

          1 SecurityContext context = SecurityContextHolder.getContext();
          2 
          3 Authentication authentication = context.getAuthentication();

              但是,ThreadLoacl不能跨越多個請求存在,所以,集成過濾器在請求開始時從Http會話中取出用戶認證信息并創建一個SecurityContextHolder將Authentication對象保存在其中,在請求結束之后,在從SecurityContextHolder中獲取Authentication對象并將其放回Http會話中,共下次請求使用,從而達到了跨越多個請求的目的。集成過濾器還有其它的實現,可以參考相關文檔。

          提示:
          集成過濾器必須在其它過濾器之前被使用。
           

              logoutFilter(退出過濾器) ,退出登錄操作:

           1 <bean id="logoutFilter"
           2 
           3     class="org.springframework.security.ui.logout.LogoutFilter">
           4 
           5     <constructor-arg value="/index.jsp"/>
           6 
           7     <constructor-arg>
           8 
           9        <list>
          10 
          11            <!-- 實現了LogoutHandler接口(logout方法) -->
          12 
          13            <ref bean="rememberMeServices"/>
          14 
          15            <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
          16 
          17        </list>
          18 
          19     </constructor-arg>
          20 
          21 </bean>


          posted @ 2009-04-21 16:11 wesley1987 閱讀(622) | 評論 (0)編輯 收藏

          2008年12月23日

           

                            項目實訓心得

                       在這一個多月的項目實訓過程,我感到是我專業學習中收獲非常大的一個月。在這個月里,我體驗到了團隊合作的經驗,編程過程中的樂趣,以及將學習應用到實際、從實踐中學習的豐收感。

                        這一個月里,得到了二個最寶貴體驗:一是參與了一個團隊合作的、有很強多同模塊相互性、和一套完整生命周期流程的工程項目。這一套項目按照軟件工程的流程一步步走下來,經歷了需求分析,詳細設計,實際編碼和測試這一系列階段。一步一步慢慢的走下來。雖然對于真實的項目來說,這個項目的復雜度和規模并不是很大,邏輯要求也不是太嚴格。但是對于只參加一些3-4人的項目編程的我來說,已經第一次讓我體真正的體驗到將編程作為一項工程來執行的難得經驗。

                        第二個體驗是詳細設計中,將軟件架構和分層的思想以及簡單的工程模式等應用到了項目中。使用框架等方式,非常有效的提高了代碼的復用和工程的可維護性,雖然多層結構看似麻煩,但實際上它很大的降低了設計的復雜度,在實際的體驗中感到,使用了框架后的模塊,維護起來清晰了很多,容易了很多,降低了耦合,同時增強了模塊間的交互和重用。

                        隨著整個工程的流程一步步進行,我們看到了一個工程的一次次成長。項目伊始,我們得到了項目需求文檔(我想這一步在實際中也應該是由項目人員精心設計才完成的),對于工程的不同用例,將工程分為了六個模塊,并對應的將組員分為了六組。我們的第一步是完成對需求文檔的理解,而成果就是對應了各個模塊的實際功能的靜態頁面,因為軟件客戶最后體驗所有需求的功能實現就是通過操作頁面來實現,所以頁面要在客戶需求的角度去考慮,同時要將需求的功能都賦予體現。在這個過程中,大家除了按功能分化出頁面分類外,大部分時間還用來精心設計頁面的風格。頁面布局和菜單中大量用到了JavaScriptCSS。和以我往設計頁面時不同的是,為了讓大家可以公用這些設計,在頁面的布局中不能太復雜,甚至幾乎是不能在需要統一的地面對整體的布置有任何復雜的干預。所有希望統一的部分都要在公共的CSSJavaScript中做出方便統一使用的類或方法,在頁面本身的代碼中幾乎看不到布局設計,只有功能組件。

                        在頁面設計通過審核之后就是詳細設計階段了,在這階段的前幾天我們犯了一個順序錯誤,直接從數據庫著手。結果由于項目的功能的復雜性和模塊之間太多需要交互的地方,使得數據庫的設計進行的很緩慢。經過老師的提點我們改為從程序編碼的框架開始著手。聯系各功能的具體實現來設計編碼的層次結構(框架詳細設計在下一節),劃分出公共平臺。這樣再從各模塊的功能及其交互劃分來聯系設計數據庫就變的清晰了很多。在設計過程中我們還使用了E-R圖來設計出關系數據庫,即從參與的對象和對象之間的關系最終設計出數據庫的方法。在這次設計中發現自己在利用一些系統的理論進行整體的數據庫模型設計方面還存在很多不足。數據庫完成后,對框架的設計也基本完成,公共的分頁設計,數據庫連接與關閉,工程的文件結構和工程的環境也在幾次討論后完成統一設計。

                        由于之前對struts有了一定的了解,所以我在需求分析階段就開始嘗試著著手對幾個簡單模塊的實現編碼,之后在詳細設計階段中,每次討論后新加的內容都需要對已經完成的代碼進行一次大的修改。隨著代碼的增長,嘗試了很多種文件結構。之后引入項目的框架也經歷了很大的修改和許多次的嘗試。此外的修改還包括BaseAction的引入,DispatchAction的引入,使用struts異常處理等,并做好工程備份及將修改記錄在日報中。在這一次次的修改中讓我受益匪淺,對這些設計和修改有了更深刻的體會。這樣在詳細設計階段的過程中,框架設計都已經在編碼中事先進行了實現和測試,一些功能在寫好后被分離出來作為公共平臺。終于在小組開始編碼時確定出了統一并詳細完整的的工程的全部環境,項目的框架結構和整體編碼方式。我的編碼實現和單元測試也基本完成。

                        在兩周的編碼過程中,我主要是和吉利一起協助各模塊編碼,增加各模塊間交流,在這期間也解決問題的過程中學到知識。經過全體組員兩周的努力工作,終于進入了測試階段。我和吉利負責整體測試,測試聯結了所有模塊之后,可以順利的完成全套的流程。讓整個設計可以在6個流程中一步步的走下去,同時保證數據庫中所有數據和狀態的正確性。隨著測試一次次的進行,問題漸漸被全部排除,經過3次測試之后,基本可以完全順利的走完全套流程。

                         

                        我們這次工程中使用的是四層結構的框架,即將MVC三層結構的同時,將model模型層分成了model模型層和DAO持久層。其中又根據工廠模式分出DAO接口,beanfactoryservicemanager)提供DAO實現。

                        結構實現:首先我們根據框架,設計出相應的文件結構。視圖層即所有JSP文件,和配置文件一起由eclipse的自動生成單獨分在WebRoot下,六模塊的頁面分別分于六個子目錄下。所有的公共頁面和jscss目錄也放入WebRoot下。由于這次項目中模塊間的功能頁面基本是完全相互獨立的,這為在實現視圖層和控制層之間的頁面跳轉控制帶來很大的方便。代碼目錄(src)下為六個模塊的六個目錄,公共代碼目錄(platform),以及后加入的驗證模塊的目錄(validate)。除公共目錄外,各模塊下代碼分為5個目錄:ActionmodelFormmanagerdao。(這里有兩個命名的失誤,根據實際的使用,model的名字應該叫bean更合適,而這里manager一般在框架中稱為service。但我們已經有了稱為service的模塊名稱。)這里的ActionForm對應了struts中的組件,DAO層和model-bean一起完成了操作的具體實現,

                        視圖層view:總體框架上,我們使用的是frameset來實現,不過聽老師說現在流行的使用japinclude結合div等來實現頁面框架。在之后編碼中,因為frameset出現了一個問題,就是用來驗證攔截的過濾器無法刷新整個框架,使得攔截后的頁面只能顯示在被操作的frame中。但是frameset的好處是框架分離的很好,在實現jsp編碼中幾乎完全不用去考慮框架。我不知道用include是否能做到。以前雖然都使用的include,但是是在每個頁面中都要加入include。有時還會影響布局。在編碼過程中,我們用JavaScript實現了很多很好用的效果,比如選擇時間的窗口,表單的正則表達式驗證,表格的變色效果等,封裝到公共的js文件中,調用起來很方便。在這次jap編程中,我終于由最初的在頁面中堆滿java代碼,轉變為只使用一些JSTLEL語句和struts標簽處理邏輯,美觀了頁面編碼,同時讓頁面更專注于顯示層。但這里我對EL語句和純標簽語句又有些難以取舍。EL語句在頁面代碼中雖然不如單用標簽顯得純粹美觀,但是EL表達式簡約的表現風格讓實現和維護變得容易了很多。

                        控制層Action的設計一是使用了DispatchAction,將多個Action類合并,方便了管理。二在公共部分中定義了BaseAction,由這個類去繼承strutsDispatchAction。之后我們的所有Action都去繼承這個BaseAction。這樣在需要對Action進行統一處理,以及定義一些供Action公共使用的方法時就可以在這個BaseAction中修改。雖然在這次項目中,BaseAction只定義了個用于處理字符亂碼的方法公共使用,但由此即可瞥見對于更復雜的Action統一處理這種設計也能從容應對。由于是分模塊進行,于是我們將strutsxml配置文件也分為對應各個模塊,使用多xml的配置方式,而這也需要對命名規則等很多方面有更好的協調和統一。在這次控制層的實現中,我起初還是像以前一樣對很多不同的驗證,模型層返回的異常都在Action中處理并跳轉。在之后的修改中,逐漸將這些處理都改至模型層Manager中,由Manager取用持久層的操作方法,實現所有業務邏輯處理。

                        具體實現功能的模型層中,我們為每個DAO定義了接口和實現類,這也是我第一次將接口真正應用到程序中。同時我們在每個模塊的DAO中應用了工廠模式,由一個factory類實現所有DAO的單例生成。之后在Manager中調用這個實例實現操作。而這個Manager同時本身也是單例實現的,由Action進行靜態調用。可見其中實現Action控制層和DAO持久層交互的就是Manager模型層,并將兩者嚴格的分離開來。同時在Manager中還集合處理了所有來至業務功能邏輯和底部數據庫的所有異常。因為數據庫的連接也是在Manager中創建的,但這不影響持久層的獨立性,因為這是考慮到有時一次業務操作會進行多個數據庫操作、調用多個數據庫方法,將連接在模型層中創建更便于數據庫的高效使用。模型層中對異常的集中處理,更簡化了上下控制層和模型層的實現,使其更專注于各自的業務實現。在異常處理上,使用了struts的一種異常處理機制,在xml配置文件中進行異常配置。這樣在Manager中將異常拋出,由struts實現異常跳轉和提示。同時我們還將自定義的異常處理類也作為公共類公用,這樣就可以在需要的時候對異常進行統一的處理。

                        在持久層的實現上,我們使用了tomcat數據庫連接池,在編碼中將數據庫連接等方法封裝到公共類中,并且將連接數據源作靜態單例實現,以提高數據庫調用的效率。在DAO的設計方面,我們主要針對實際的操作對象和對應的數據庫進行DAO層方法的封裝。每個方法盡量實現一些簡單的操作。這樣在不同模塊直接有數據和操作交互的時候,只在模型層只要去各個模塊的DAO中取得需要的方法加以組合,實現自己的業務處理。很好的提高了代碼的復用性和可維護性,降低了各個模塊間數據交互處理的設計復雜度。

              //文采太爛, 結尾的感慨段就不發了

          posted @ 2008-12-23 21:38 wesley1987 閱讀(748) | 評論 (0)編輯 收藏

          2008年12月15日

          今天一個詭異的問題弄了我半天,最后發現原因如下:

          在HTML的head中 引入外部script:
                  <script src="<%=path%>/js/service.js" type="text/javascript" ></script>
          之后又寫內部script (內容無關)
          <script type="text/javascript">
            function SecondType(){
            if (document.check.classTwo.value==1){
             stext.style.display="inline";
            }

            else{
             stext.style.display="none";
            }

           }

           function FirstType(select,forwards){
            if (document.check.classOne.value==1){
              ftext.style.display = "inline";
              document.check.classTwo.value=1;
              SecondType();
            }
          else{
             ftext.style.display = "none";
             window.location="<%=path%>/service/good.do?operation=getClass&classone="+select.value+"&forward="+forwards; 
            }

           }

          </script>
          一切正常,
          但是 如果將head中的改為
          <script src="<%=path%>/js/service.js" type="text/javascript"  />變了下結尾
          引入的外部script任然好用,但是下面的內部script就完全不執行。并伴隨很多奇怪的顯示效果。

          posted @ 2008-12-15 19:21 wesley1987 閱讀(567) | 評論 (0)編輯 收藏

          轉自網上的一篇很詳細的關于servlet中各種出現亂碼的問題即解決方案:
          http://www.diybl.com/course/3_program/java/javajs/200829/99730.html

          (1)前言:
          解決web程序的國際化問題,必須在任何地方使用UTF-8對字符進行編碼。(包括:數據庫設置為:UTF-8,web頁面也要設置為:UTF-8)
          這樣做的好處在于可以解決在web上不止中文字符編碼問題,所有的字符編碼都統一使用UTF-8,實現了語言的國際化。同時在保存數據到
          數據庫時候也省去了編碼轉換的問題。
          在JSP或JSF應用中使用到Servlet,我們通過使用Servlet過濾器進行編碼轉換,也就是制定編碼轉換為UFT-8。

          (2)Servlet和JSP過濾器Filter簡介:
          servlet API的2.3版本中最重要的一個新功能就是能夠為servlet和JSP頁面定義過濾器。過濾器提供了某些早期服務器所支持的非標準“servlet鏈接”的一種功能強大且標準的替代品。
          過濾器是一個程序,它先于與之相關的servlet或JSP頁面運行在服務器上。過濾器可附加到一個或多個servlet或JSP頁面上,并且可以檢查進入這些資源的請求信息。在這之后,過濾器可以作如下的選擇:
          - 以常規的方式調用資源(即,調用servlet或JSP頁面)。
          - 利用修改過的請求信息調用資源。
          - 調用資源,但在發送響應到客戶機前對其進行修改
          - 阻止該資源調用,代之以轉到其他的資源,返回一個特定的狀態代碼或生成替換輸出。
          過濾器提供了幾個重要好處。
               首先,它以一種模塊化的或可重用的方式封裝公共的行為。你有30個不同的serlvet或JSP頁面,需要壓縮它們的內容以減少下載時間嗎?沒問題:構造一個壓縮過濾器(參閱第11節),然后將它應用到30個資源上即可。
              其次,利用它能夠將高級訪問決策與表現代碼相分離。這對于JSP特別有價值,其中一般希望將幾乎整個頁面集中在表現上,而不是集中在業務邏輯上。例如,希望阻塞來自某些站點的訪問而不用修改各頁面(這些頁面受到訪問限制)嗎?沒問題:建立一個訪問限制過濾器(參閱第8節)并把它應用到想要限制訪問的頁面上即可。
              最后,過濾器使你能夠對許多不同的資源進行批量性的更改。你有許多現存資源,這些資源除了公司名要更改外其他的保持不變,能辦到么?沒問題:構造一個串替換過濾器(參閱第10節),只要合適就使用它。
              但要注意,過濾器只在與servlet規范2.3版兼容的服務器上有作用。如果你的Web應用需要支持舊版服務器,就不能使用過濾器。
          建立一個過濾器涉及下列五個步驟:
          1、建立一個實現Filter接口的類。這個類需要三個方法,分別是:doFilter、init和destroy。doFilter方法包含主要的過濾代碼,init方法建立設置操作,而destroy方法進行清楚。
          2、在doFilter方法中放入過濾行為。doFilter方法的第一個參數為ServletRequest對象。此對象給過濾器提供了對進入的信息(包括表單數據、cookie和HTTP請求頭)的完全訪問。第二個參數為ServletResponse,通常在簡單的過濾器中忽略此參數。最后一個參數為FilterChain,如下一步所述,此參數用來調用servlet或JSP頁。
          3、調用FilterChain對象的doFilter方法。Filter接口的doFilter方法取一個FilterChain對象作為它的一個參數。在調用此對象的doFilter方法時,激活下一個相關的過濾器。如果沒有另一個過濾器與servlet或JSP頁面關聯,則servlet或JSP頁面被激活。
          4、對相應的servlet和JSP頁面注冊過濾器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素。
          5、禁用激活器servlet。防止用戶利用缺省servlet URL繞過過濾器設置。

          doFilter方法:

          1 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          2  throws ServletException, IOException
          3 {
          4  HttpServletRequest req = (HttpServletRequest)request;
          5  System.out.println(req.getRemoteHost() + " tried to access " +req.getRequestURL() +" on " + new Date() + ".");
          6  chain.doFilter(request,response);
          7 }


          在web.xml中進行部署
          分別是:filter和filter-mapping。filter元素向系統注冊一個過濾對象,filter-mapping元素指定該過濾對象所應用的URL。

          <filter>
          <filter-name>ChangeCodeFilter</filter-name>
          <display-name>ChangeCodeFilter</display-name>
          <description></description>
          <filter-class>com.cnc.SetCharacterEncodingFilter</filter-class>
          </filter>
          <filter-mapping>
          <filter-name>SetCharacterEncodingFilter</filter-name>
          <url-pattern>/SetCharacterEncodingFilter</url-pattern>
          </filter-mapping>

          1.filter元素
          filter元素位于部署描述符文件(web.xml)的前部,所有filter-mapping、servlet或servlet-mapping元素之前。filter元素具有如下六個可能的子元素:
           :icon  這是一個可選的元素,它聲明IDE能夠使用的一個圖象文件。
           : filter-name  這是一個必需的元素,它給過濾器分配一個選定的名字。
           : display-name  這是一個可選的元素,它給出IDE使用的短名稱。
           : description  這也是一個可選的元素,它給出IDE的信息,提供文本文檔。
           : filter-class  這是一個必需的元素,它指定過濾器實現類的完全限定名。
           : init-param  這是一個可選的元素,它定義可利用FilterConfig的getInitParameter方法讀取的初始化參數。單個過濾器元素可包含多個init-param元素。
          2.filter-mapping元素
            filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三個可能的子元素::
            filter-name 這個必需的元素必須與用filter元素聲明時給予過濾器的名稱相匹配。
            url-pattern  此元素聲明一個以斜杠(/)開始的模式,它指定過濾器應用的URL。所有filter-mapping元素中必須提供url-pattern或servlet-name。但不能對單個filter-mapping元素提供多個url-pattern元素項。如果希望過濾器適用于多個模式,可重復整個filter-mapping元素。
          :servlet-name  此元素給出一個名稱,此名稱必須與利用servlet元素給予servlet或JSP頁面的名稱相匹配。不能給單個filter-mapping元素提供多個servlet-name元素項。如果希望過濾器適合于多個servlet名,可重復這個filter-mapping元素。

          (3)在Rational Application Developer 中的建立字符轉換過濾器:
          1.新建-web-過濾器:SetCharacterEncodingFilter
          會在web.xml中產生如上代碼:

          2.在過濾器的doFilter方法中添加如下代碼:

          public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {
            arg0.setCharacterEncoding(
          "UTF-8"); //設定字體編碼為UTF-8
            arg2.doFilter(arg0, arg1);// 傳遞控制到下一個過濾器
           }

          3.在web.xml中進行部署
          在web.xml的過濾器-編輯器中選擇:servlet 映射 - 添加 - Faces Servlet
          會在web.xml中產生如下代碼:
          <filter-mapping>
          <filter-name>SetCharacterEncodingFilter</filter-name>
          <servlet-name>Faces Servlet</servlet-name>
          </filter-mapping>

          (4)其他參考信息
          tomcat下中文的徹底解決
          (一)    JSP頁面上是中文,但是看的是后是亂碼:
          解決的辦法就是在JSP頁面的編碼的地方<%@ page language="java" contentType="text/html;charset=GBK" %>,因為Jsp轉成Java文件時的編碼問題,默認的話有的服務器是ISO-8859-1,如果一個JSP中直接輸入了中文,Jsp把它當作ISO8859-1來處理是肯定有問題的,這一點,我們可以通過查看Jasper所生成的Java中間文件來確認
          (二)    當用Request對象獲取客戶提交的漢字代碼的時候,會出現亂碼:
          解決的辦法是:要配置一個filter,也就是一個Servelet的過濾器,代碼如下:

          import java.io.IOException;
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.UnavailableException;
          /**
           * Example filter that sets the character encoding to be used in parsing the
           * incoming request
           
          */
          public class SetCharacterEncodingFilter implements Filter {
              
          /**
               * Take this filter out of service.
               
          */
              
          public void destroy() {
              }
              
          /**
               * Select and set (if specified) the character encoding to be used to
               * interpret request parameters for this request.
               
          */
              
          public void doFilter(ServletRequest request, ServletResponse response,
              FilterChain chain)
          throws IOException,ServletException {
              request.setCharacterEncoding(
          "GBK");
              
          // 傳遞控制到下一個過濾器
              chain.doFilter(request, response);
              }
              
          public void init(FilterConfig filterConfig) throws ServletException {
              }
          }

           

           

          配置web.xml

          <
          filter>
          <filter-name>Set Character Encoding</filter-name>
          <filter-class>SetCharacterEncodingFilter</filter-class>
          </filter>
          <filter-mapping>
          <filter-name>Set Character Encoding</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>

          如果你的還是出現這種情況的話你就往下看看是不是你出現了第四中情況,你的Form提交的數據是不是用get提交的,一般來說用post提交的話是沒有問題的,如果是的話,你就看看第四中解決的辦法。
          還有就是對含有漢字字符的信息進行處理,處理的代碼是:
          package dbJavaBean;
          public class CodingConvert
          {  
           public CodingConvert()
           {
            //
           }
           public String toGb(String uniStr){
               String gbStr = "";
               if(uniStr == null){
             uniStr = "";
               }
               try{
             byte[] tempByte = uniStr.getBytes("ISO8859_1");
             gbStr = new String(tempByte,"GB2312");
               }
            catch(Exception ex){
              }
               return gbStr;
           }
            
           public String toUni(String gbStr){
               String uniStr = "";
               if(gbStr == null){
             gbStr = "";
               }
               try{
             byte[] tempByte = gbStr.getBytes("GB2312");
             uniStr = new String(tempByte,"ISO8859_1");
               }catch(Exception ex){
              }
              return uniStr;
           }
          }
          你也可以在直接的轉換,首先你將獲取的字符串用ISO-8859-1進行編碼,然后將這個編碼存放到一個字節數組中,然后將這個數組轉化成字符串對象就可以了,例如:
          String str=request.getParameter(“girl”);
          Byte B[]=str.getBytes(“ISO-8859-1”);
          Str=new String(B);
          通過上述轉換的話,提交的任何信息都能正確的顯示。
          (三)    在Formget請求在服務端用request. getParameter(“name”)時返回的是亂碼;按tomcat的做法設置Filter也沒有用或者用request.setCharacterEncoding("GBK");也不管用問題是出在處理參數傳遞的方法上:如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法進行處理的話前面即使是寫了:
          request.setCharacterEncoding("GBK");
          response.setContentType("text/html;charset=GBK");
          也是不起作用的,返回的中文還是亂碼!!!如果把這個函數改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。
          同樣,在用兩個JSP頁面處理表單輸入之所以能顯示中文是因為用的是post方法傳遞的,改成get方法依舊不行。
          由此可見在servlet中用doGet()方法或是在JSP中用get方法進行處理要注意。這畢竟涉及到要通過瀏覽器傳遞參數信息,很有可能引起常用字符集的沖突或是不匹配。
          解決的辦法是:
          1) 打開tomcat的server.xml文件,找到區塊,加入如下一行:
          URIEncoding=”GBK”
          完整的應如下:
          <Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/>
          2)重啟tomcat,一切OK。
          需要加入的原因大家可以去研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的這個文件就可以知道原因了。需要注意的是:這個地方如果你要是用UTF-8的時候在傳遞的過程中在Tomcat中也是要出現亂碼的情況,如果不行的話就換別的字符集。
          (四)    JSP頁面上有中文,按鈕上面也有中文,但是通過服務器查看頁面的時候出現亂碼:
               解決的辦法是:首先在JSP文件中不應該直接包含本地化的消息文本,而是應該通過<bean:message>標簽從Resource Bundle中獲得文本。應該把你的中文文本放到Application.properties文件中,這個文件放在WEB-INF/classes/*下,例如我在頁面里有姓名,年齡兩個label,我首先就是要建一個Application.properties,里面的內容應該是name=”姓名” age=”年齡”,然后我把這個文件放到WEB-INF/classes/properties/下,接下來根據Application.properties文件,對他進行編碼轉化,創建一個中文資源文件,假定名字是Application_cn.properties。在JDK中提供了native2ascii命令,他能夠實現字符編碼的轉換。在DOS環境中找到你放置Application.properties的這個文件的目錄,在DOS環境中執行一下命令,將生成按GBK編碼的中文資源文件Application_cn.properties:native2ascii ?encoding gbk Application.properties Application_cn.properties執行以上命令以后將生成如下內容的Application_cn.properties文件:name=\u59d3\u540d age=\u5e74\u9f84,在Struts-config.xml中配置:<message-resources parameter="properties.Application_cn"/>。到這一步,基本上完成了一大半,接著你就要在JSP頁面上寫<%@ page language="java" contentType="text/html;charset=GBK" %>,到名字的那個label是要寫<bean:message key=”name”>,這樣的化在頁面上出現的時候就會出現中文的姓名,年齡這個也是一樣,按鈕上漢字的處理也是同樣的。
          (五)    寫入到數據庫是亂碼:
          解決的方法:要配置一個filter,也就是一個Servelet的過濾器,代碼如同第二種時候一樣。
          如果你是通過JDBC直接鏈接數據庫的時候,配置的代碼如下:jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK,這樣保證到數據庫中的代碼是不是亂碼。
          如果你是通過數據源鏈接的化你不能按照這樣的寫法了,首先你就要寫在配置文件中,在tomcat 5.0.19中配置數據源的地方是在C:\Tomcat 5.0\conf\Catalina\localhost這個下面,我建立的工程是workshop,放置的目錄是webapp下面,workshop.xml的配置文件如下:
          <!-- insert this Context element into server.xml -->
          <Context path="/workshop" docBase="workshop" debug="0"
          reloadable="true" >
            <Resource name="jdbc/WorkshopDB"
                         auth="Container"
                         type="javax.sql.DataSource" />
            <ResourceParams name="jdbc/WorkshopDB">
              <parameter>
                <name>factory</name>
                <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
              </parameter>
              <parameter>
                <name>

          maxActive</name>
                <value>100</value>
              </parameter>
              <parameter>
                <name>maxIdle</name>
                <value>30</value>
              </parameter>
             
              <parameter>
                <name>maxWait</name>
                <value>10000</value>
              </parameter>
                <parameter>
               <name>username</name>
               <value>root</value>
              </parameter>
              <parameter>
               <name>password</name>
               <value></value>
              </parameter>
              <!-- Class name for mm.mysql JDBC driver -->
              <parameter>
                 <name>driverClassName</name>
                 <value>com.mysql.jdbc.Driver</value>
          </parameter>
             <parameter>
                <name>url</name>
           <value><![CDATA[jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK]]></value>
              </parameter>
            </ResourceParams>
          </Context>
          粗體的地方要特別的注意,和JDBC直接鏈接的時候是有區別的,如果你是配置正確的化,當你輸入中文的時候到數據庫中就是中文了,有一點要注意的是你在顯示數據的頁面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>這行代碼的。需要注意的是有的前臺的人員在寫代碼的是后用Dreamver寫的,寫了一個Form的時候把他改成了一個jsp,這樣有一個地方要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他該過來,因為在jsp的提交的過程中緊緊就是POST和GET兩種方式,但是這兩種方式提交的代碼在編碼方面還是有很大不同的,這個在后面的地方進行說明.


          文章出處:http://www.diybl.com/course/3_program/java/javajs/200829/99730_3.html

          posted @ 2008-12-15 17:09 wesley1987 閱讀(488) | 評論 (0)編輯 收藏

          一. 使用 方法調用處理中文:
              public static String changeStr(String str){    
                  
          if(str==null)return null;
                  String temp
          =null;
                  
          try {
                      temp 
          = new String(str.getBytes("ISO-8859-1"));
                  } 
          catch (UnsupportedEncodingException e) {
                      
                      e.printStackTrace();
                  }
                  
          return temp;
              }

            我們將這個方法作為靜態寫入了BaseAction中,使所有的方法都能調用。
              String offername = changeStr(request.getParameter("offername"));
          這種方法的好處是: 無論是POST/GET的頁面表單,還是重寫的URL他都一并處理了。寫起來也簡單
          可問題是:對于所有頁面參數幾乎都要調用一下這個方法,對于大的工程就很不合適了。
                          特別是參數很多的Form中,所有的參數都要用它處理一次。雖然我把這個處理寫入了驗證中自動調用。
                      但是還是感覺比較麻煩。

           

          二. 使用 過濾器 Filter
          1 新建一個java文件:SetCharacterEncodingFilter


           
          import java.io.IOException;
           
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
           
          public class CharacterEncodingFilter implements Filter {
           
              
          private FilterConfig config;
              
          private String encoding;
           
              
          public void destroy() {
                  
          // 銷毀配置
                  this.config = null;
           
              }
           
              
          public void doFilter(ServletRequest request, ServletResponse response,
                      FilterChain chain) 
          throws IOException, ServletException {
                  
          // 如果編碼已經配置, 則使用該編碼.
                  if(this.encoding != null) {
                      request.setCharacterEncoding(
          this.encoding);
                  }
                  
          // 將資源鏈到下一Filter, 如果這是最后一個Filter, 則將資源鏈到目的位置.
                  chain.doFilter(request, response);
           
              }
           
              
          public void init(FilterConfig config) throws ServletException {
                  
          // 方便銷毀配置
                  this.config = config;
                  
          // 讀取web.xml中CharacterEncodingFilter內的初始編碼參數
                  this.encoding = this.config.getInitParameter("encoding");
           
              }

          2 在web.xml中 根節點下加入
          <!-- 設置request編碼方式  -->
             
          <filter>
                  
          <filter-name>Set Character Encoding</filter-name>
                  
          <filter-class>com.neusoft.struts.platform.SetCharacterEncodingFilter</filter-class>
                  
          <init-param>
                      
          <param-name>encoding</param-name>
                      
          <param-value>GB2312</param-value>
                  
          </init-param>
                  
          <init-param>
                      
          <param-name>ignore</param-name>
                      
          <param-value>true</param-value>
                  
          </init-param>
              
          </filter>
              
          <filter-mapping>
                  
          <filter-name>Set Character Encoding</filter-name>
                  
          <url-pattern>*</url-pattern>
             
          </filter-mapping>

          使用過濾器 可謂是一勞永逸,所有頁面表單是POST的請求,即所有struts中的Form基本都OK了。
          但注意:它也僅對POST請求有效。對于GET請求和重寫URL的請求,它也會去處理,但由于他們和POST的編碼區別,
          過濾器會把他們過濾成??

            解決方法:
          找到Tomcat安裝目錄內conf文件夾下的server.xml文件,
          給其中的連接器元素Connector添加屬性: URIEncoding, 屬性值為: UTF-8.

          1  <Connector port="8080" protocol="HTTP/1.1" 
          2                connectionTimeout="20000" 
          3                redirectPort="8443"
          4                URIEncoding="UTF-8" />

           

          關于亂碼詳細問題即解決,見 亂碼問題詳解

          posted @ 2008-12-15 14:46 wesley1987 閱讀(660) | 評論 (1)編輯 收藏

          2008年12月9日

          1,操作對象,將數據庫里的表映射為持久化類。
              一個商品類 Good,一個供應商 Offer類,一個Offer可以提供多個商品。
          商品表字段: goodId, offerId, goodName, price .
          供應商字段:    offerId ,offerName.
          Good.hbm.xml
          :<hibernate-mapping>
              <class name="com.neusoft.Good" table="GOOD" schema="WULIU">
                  <id name="goodid" type="java.lang.Long">
                      <column name="GOODID" precision="10" scale="0" />
                      <generator class="assigned" />
                  </id>
                  <many-to-one name="offer" class="com.myweb.Offer" fetch="select">
                      <column name="OFFERID" precision="10" scale="0" />
                  </many-to-one>

                  <property name="goodname" type="java.lang.String">
                      <column name="GOODNAME" length="40" />
                  </property>
                  <property name="price" type="java.lang.Double">
                      <column name="PRICE" precision="10" />
                  </property>

                  </property>
              </class>
          </hibernate-mapping>

          Offer.hbm.xml

          <hibernate-mapping>
              <class name="com.neusoft.Offer" table="OFFER" schema="WULIU">
                  <id name="offerid" type="java.lang.Long">
                      <column name="OFFERID" precision="10" scale="0" />
                      <generator class="assigned" />
                  </id>
                  <property name="offername" type="java.lang.String">
                      <column name="OFFERNAME" length="30" />
                  </property>
                  <set name="goods" inverse="true" lazy="true" cascade="delete" >
                      <key>
                          <column name="OFFERID" precision="10" scale="0" />
                      </key>

                      <one-to-many class="com.neusoft.Good" />
          <!--java.util.Set : private Set goods = new HashSet(0);-->

                  </set>
              </class>
          </hibernate-mapping>

          lazy="true" 與特定的Offer對象相對應的Good不會像Offer對象一樣由同一個SQL查詢獲取
          inverse="true" 表示用此表示兩者之間的關系。
          cascade="delete" 級聯刪除

          由此配置文件可生成對應的持久化類(即JavaBeans類)  Good.java, Offer.java

          2. org.hibernate.cfg.Configuration 創建一個HibernateSessionFactory。
          import org.hibernate.Session;
          import org.hibernate.cfg.Configuration;

          public class HibernateSessionFactory {
                    
                    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";//xml中配置了數據庫的連接信息。
                  private static org.hibernate.SessionFactory sessionFactory;
                  
          private static String configFile = CONFIG_FILE_LOCATION;

              
          static {
                  
          try {
                      configuration.configure(configFile);
                      sessionFactory 
          = configuration.buildSessionFactory();
                  } 
          catch (Exception e) {
                      System.err
                              .println(
          "%%%% Error Creating SessionFactory %%%%");
                      e.printStackTrace();
                  }
              }
              
          private HibernateSessionFactory() {
              }

              public static org.hibernate.SessionFactory getSessionFactory() {
                    return sessionFactory;
               }

          }
          (這是用Myeclipse自動生成的代碼中一小段)
          創建了SessionFactory,就可以用getSession方法來實現操作了,如
          public void save(Good transientInstance) {
                    log.debug("saving Good instance");
                try {
                         getSession().save(transientInstance);
                         log.debug("save successful");
                } catch (RuntimeException re) {
                         log.error("save failed", re);
                         throw re;
                }
           }




          posted @ 2008-12-09 15:10 wesley1987 閱讀(136) | 評論 (0)編輯 收藏

          2008年12月4日

          模塊的實現寫的差不多了,可是 每個頁面的活動都要一個Action,3個對象的增刪改查 就有14個Action。終于今天組長發飆了,要改成DispatchAction。現上網查查怎么用。。找到個本博客中的文章放入收藏了。

          http://www.aygfsteel.com/jxhkwhy/archive/2007/01/21/95177.html

          把增刪改查都放到一個Action中,然后在XML中為每個方法配一個
          < action

                attribute = "addUserForm"

                input = "/addUser.jsp"

                name = "addUserForm"

                parameter="method"

                path = "/addUser"

                scope = "request"

                type="com.why.struts.action.UserAction" >

              </ action >
          其實如果使用的Form(name=“xxxForm”)是一樣的話,幾個方法配一個<action>也行。用多個的時候,注意path不要寫成一樣的了。
          注意parameter的值,作為JSP跳轉的do的參數就可以了。基本上配置方面 和一般<action>區別就是含有同一個type地址和parameter

          <html:link href="addUser.do?method=addUser">Add User</html:link>

          參數值為Action里的方法名,如這個 對應為 Action中的
          addUser (ActionMapping mapping,ActionForm form, HttpServletRequest request,HttpServletResponse response)


           execute就不用在寫了。雖然不知道寫了會怎么樣。 
          下面是我自己的struts-config.xml配置: 
                      實現offer的增,刪,改,查。其中查和刪的配置寫在了一起。所以是 3個Action,注意其 path,type ,和parameter屬性。調用時用parameter的值區分。這里還可以看到定向到offerSearch的URL的使用。
          這里的name雖然相同,但是分開的原因是 我需要input這個屬性作為異常的轉回頁面。查詢和刪除都不用name 而且異常提示頁面相同,所以合并。
              <action
                
          input="/service/offerSearch.jsp"
                parameter
          ="operation"
                path
          ="/offer"
                scope
          ="request"
                type
          ="com.neusoft.struts.service.action.OfferAction">
                
          <forward name="success" path="/offer.do?operation=offerSearch&amp;offername="/>
                
          <forward name="show" path="/service/offerSearch.jsp" />
              
          </action>
              
          <action
                
          attribute="OfferForm"
                input
          ="/service/offerNew.jsp"
                parameter
          ="operation"
                name
          ="OfferForm"
                path
          ="/offerAdd"
                scope
          ="request"
                type
          ="com.neusoft.struts.service.action.OfferAction">
                
          <forward name="success" path="/offer.do?operation=offerSearch&amp;offername="/>
              
          </action>
              
          <action 
               
          attribute="OfferForm"
              name
          ="OfferForm"
              parameter
          ="operation"
              path
          ="/offerUpdate" 
              input
          ="/service/offerUpdate.jsp"
              scope
          ="request"
              type 
          ="com.neusoft.struts.service.action.OfferAction" >
               
          <forward name="success" path="/offer.do?operation=offerSearch&amp;offername="/>
              
          </action>

          對應的DispatchAction    :

          public class OfferAction extends DispatchAction {
              
              
              
          public ActionForward offerSearch(ActionMapping mapping, ActionForm form,
                      HttpServletRequest request, HttpServletResponse response) 
          throws Exception {
                  
                  String offername 
          = changeStr(request.getParameter("offername"));
                  request.setAttribute(
          "offername", offername);
                  
                  HttpSession session 
          = request.getSession();
                  IPageList pageList;

                  
          if(request.getParameter("page")==null){            //來自查詢表單的請求
                      pageList = new PageList(1,OfferManager.getInstance().getOfferList(offername));
                      session.setAttribute(
          "list", pageList.getResultList());
                      request.setAttribute(
          "pageList", pageList);
                  }
                  
          else{                                            //來自分頁鏈接的請求
                      int page = Integer.parseInt(request.getParameter("page"));
                      pageList 
          = new PageList(page,OfferManager.getInstance().getOfferList(offername));
                      session.setAttribute(
          "list", pageList.getResultList());
                      request.setAttribute(
          "pageList", pageList);
                  }        
                  
          return mapping.findForward("show");
              }

              
          public ActionForward offerAdd(ActionMapping mapping, ActionForm form,
                      HttpServletRequest request, HttpServletResponse response) 
          throws Exception {

                  OfferForm offer 
          = (OfferForm) form;
                  
                  OfferManager.getInstance().addOffer(offer);
                  
                  
          return mapping.findForward("success");
              }

              
          public ActionForward offerUpdate(ActionMapping mapping, ActionForm form,
                      HttpServletRequest request, HttpServletResponse response) 
          throws Exception {
                  
                  OfferForm offer 
          = (OfferForm) form;

                  OfferManager.getInstance().offerUpdate(offer);
                  
          return mapping.findForward("success");
                  
              }

              
          public ActionForward offerDelete(ActionMapping mapping,ActionForm Form,
                              HttpServletRequest request,HttpServletResponse response)
          throws Exception{
                  
                  String id 
          = request.getParameter("offerId");
                  
          if(id!=null){
                      OfferManager.getInstance().offerDelete(Integer.parseInt(id));
                  }
                  
          return mapping.findForward("success");
              }
          }



          posted @ 2008-12-04 17:12 wesley1987 閱讀(418) | 評論 (0)編輯 收藏

          2008年11月27日

          今天試著不用自動生成,手動配置了一次struts。結果是 傳到Action的form 一直為空,上網查尋后原因是:

          在struts-config.xml   <action>里的name屬性值要和你的formbean里的name屬性值要一致,validate屬性值要為true,要是沒寫默認為true

          看來有必要詳看下struts-config.xml的配置。以下是復制于網上的“struts-config.xml詳解”:
           http://www.9php.com/college/net/java/qt/2006/07/522422119091.html
          Struts的核心是struts-config.xml配置文件,在這個文件里描述了所有的Struts組件。在這里包括配置主要的組件及次要的組件,下面是struts-config.xml包含主要元素的內容:

          一、        struts-config.xml的主要元素:
          <?xml  version=”1.0”  encoding=”ISO-8859-1”?>
          <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">
          <struts-config>
               
               <data-sources>
                       <data-source>
                       </data-source>
               </data-sources>

               <form-beans>
                       <form-bean  name =“ ”  type=“ ”   / >
               </form-beans>

              <global-exceptions />

               <global-forwards>
                       <forward  /  >
               </global-forwards>

               <action-mappings>
                       <action  /  >
               </action-mappings>

               <controller  /  >

               <message-resources  /  >

               <plug-in  />

          </struts-config>
          注意:以上各元素的順序是非常重要的,你的struts-config.xml配置文件必須按照這個順序進行配置,否則在你的容器啟動的時候就會出錯。


          二、        struts-config.xml的子元素:
          1.<icon / >子元素
               它包含<small-icon  /  >及<large-icon  /  >,它的作用是圖形化其父元素,<small-icon/>的內容是一個16x16的圖像文件,而<large-icon/>的內容是一個32x32的圖像文件。如下例子:
               <icon>
          <small-icon>
                                     /images/smalllogo.gif
          </small-icon>
          <large-icon>
                 /images/largelogo.gif
          </large-icon>
          </icon>
          2.<display-name  /  >子元素
               它提供對父元素的短文字(short  textual)描述信息,如下:
               <display-name>
                               short  textual  discription  of  its  parent  element
               </display-name>
          3.<description  /  >子元素
               它提供對父元素的完全(full-length  textual)的描述信息,如下:
          <description>
          full-length  textual  discription  of  its  parent  element
          </description>
          4.<set-property  /  >子元素
                       它用來設置它的父元素中設定的JavaBean的屬性值,它一般用在指定的GenericDataSource  屬性,擴展的ActionMappings以及擴展的  global  forwards。如下:
                       <set-property  
                               property="name  of  bean  property"              
          value="value  of  bean  property"  />
                           例如:
                           <set-property  property="driverClass"  value="org.gjt.mm.mysql.Driver"  />
                         <set-property  property="user"  value="admin"/>
                         <set-property  property="maxCount"  value="4"/>
          <set-property  property="minCount"  value="2"/>  
          <set-property  property="password"  value=""/>  
          <set-property  property="url"  value="jdbc:mysql://localhost:3306/struts"/>


          三、        配置JDBC數據源
          其配置形式如下:
          <data-sources>
          <data-source>
          <set-property  property="driverClass"  value="fully  qualified  path  of  JDBC  driver"/>
          <set-property  property="url"  value="data  source  URL"/>
          <set-property  property=”mincount”  value="the  minimum  number  of  connections  to  open"/>
          <set-property  property="password"  value="the  password  used  to  create  connections"/>
          <set-property  property="user"  value="the  username  used  to  create  connections"/>
          </data-source>
          </data-sources>
          <data-source>的屬性及其描述信息如下:
          Key        綁定在ServletContext上的DataSource實例的索引鍵,若不設定則缺省為Action.DATA_SOURCE_KEY,如果在應用程序中有多于一個的DataSource,則必須設置Key的值。
          DriverClass        所用的JDBC驅動類(必須的)如:com.microsoft.jdbc.sqlserver.SQLServerDriver
          url        所用的JDBC的URL(必須的)如:jdbc:microsoft:sqlserver://xg088:1433
          MaxCount        同時打開的最大連結數,缺省值為2(可選的)
          MinCount        同時打開的最小連結數,缺省值為1(可選的)
          User        連結到數據庫的用戶名(必須的)
          Password        連結到數據庫的密碼(必須的)
          Description        關于DataSource的描述信息(可選的)
          ReadOnly        如果設為true,則表示該連結是只讀的,缺省為false。(可選的)
          LoginTimeout        創建連結的最大允許時間,以秒為單位。(可選的)
          AutoCommit        如果為true,則每次execute之后會強制回滾。缺省為true。(可選的)
          舉例說明:
          <data-sources>
                 <data-source>
                         <set-property  property=”key”  value=”  value="WILEY_DATA_SOURCE"  />
                          <set-property  property="driverClass"  value="org.gjt.mm.mysql.Driver"  />
                          <set-property  property="url"  value="jdbc:mysql://localhost/wileyusers"  />
                          <set-property  property="maxCount"  value="5"/>
                          <set-property  property="minCount"  value="1"/>
                          <set-property  property="user"  value="sa"/>
                          <set-property  property="password"  value="yourpassword"/>
                  </data-source>
          </data-sources>


          四、        配置FormBean
          <form-bean  /  >用來定義將要綁定到Action的FormBean的實例。語法如下:
          <form-beans>
          <form-bean  name="name  used  to  uniquely  identify  a  FormBean"   type=”fully  qualified  class  name  of  FormBean"/>
                           </form-beans>
          例:
                  <form-beans>
                      <form-bean  name="lookupForm"  type="wiley.LookupForm"  />
                  </form-beans>



          五、        配置全局轉發
          全局轉發可以定義幾個<forward/>子元素,struts首先會在<action-mappings>元素中找對應的<forward>,若找不到,則到全局轉發配置中找。語法如下:
          <global-forwards>
          <forward  name="unique  target  identifier"  
          path="context-relative  path  to  targetted  resource  "/>
          </global-forwards>
          除了name及path屬性之外,還有一個redirect屬性,如果redirect設為true的時候,則用HttpServletResponse.sendRedirect()方法,否則用RequestDispatcher.forward()方法,缺省為false。
          注:如果為true,則用HttpServletResponse.sendRedirect()方法,此時存儲在原來的HttpServletRequest中的值將會丟失。
          例子:
          <global-forwards>
          <forward  name="success"  path="/welcome.jsp"/>
          <forward  name="failure"  path="/index.jsp"/>
          </global-forwards>


          六、        配置<action-mappings>
          它可以定義幾個<action  /  >子元素,它主要是定義Action實例到ActionServlet類中,語法如下:
          <action-mappings>
          <action  path="context-relative  path  mapping  action  to  a  request"
          type="fully  qualified  class  name  of  the  Action  class"
          name="the  name  of  the  form  bean  bound  to  this  Action">
          <forward  name="forwardname1"  path="context-relative  path"/>
          <forward name="forwardname2" path="context-relative path"/>
          </action>
          </action-mappings>
          <action/>屬性及其描述信息如下:
          屬  性    描 述 信 息
          Path    在瀏覽器的URL中輸入的字符(必須的)
          Type    連結到本映射的Action的全稱(可選的)
          Name    與本操作關聯的Action Bean在<form-bean/>中定義name名(可選的)
          Scope    指定ActionForm Bean的作用域(session和request),缺省為session。(可選的)
          Input    當Bean發生錯誤時返回的控制。(可選的)
          ClassName    指定一個調用這個Action類的ActionMapping類的全名。缺省用org.apache.struts.action.ActionMapping,(可選的)
          Forward    指定處理相應請求所對應的JSP頁面。(可選的)
          Include    如果沒有forward的時候,它起forward的作用。(可選的)
          Validate    若為true,則會調用ActionForm的validate()方法,否則不調用,缺省為true。(可選的)
          例子:
          <action-mappings>
              <action path="/lookupAction" 
                      type="wiley.LookupAction"
                      name="LookupForm"
                      scope="request"
                      validate="true"
                      input="/index.jsp">
                  <forward name="success" path="/quote.jsp"/>
                  <forward name="faliue" path="/index.jsp"/>
              </action>
          </action-mappings>



          七、    配置RequestProcessor
          在struts-config.xml文件中用<controller/>子元素來定義RequestProcessor,其語法格式如下:
          <controller processorClass="fully qualified class name" />
          <controller />元素屬性及其描述信息如下:
          屬  性    描  述
          processorClass    指定自定義的RequestProcessor類的全名
          BufferSize    指定用來下載所用的緩存大小。缺省是4096字節。
          contentType    定義response文本類型,缺省是text/html
          Debug    定義當前系統的除錯級別,缺省是0
          Locale    如果是true,則在用戶的session中存放Locale對象,缺省為true
          maxFileSize    指定下載文件最大的大小。缺省是250M
          multipartClass    指定去代替org.apache.struts.upload.DiskMultipartRequestHandler類的類的全名。
          Nocache    如果是true,則會關閉每個response的緩存功能。缺省是false
          TempDir    指定上載文件所用的臨時目錄。缺省值由容器決定
          例子:
           <controller processorClass="wiley.WileyRequestProcessor" />
          ② <controller    contentType="text/html;charset=UTF-8"
                                  debug="3"
                                  locale="true"
                                  nocache="true"
                                  processorClass="org.apache.struts.action.RequestProcessor"/>



          八、    配置Message Resources
          在struts-config.xml文件中用<message-resources />元素來定義消息資源。其語法如下:
                 <message-resources  parameter="wiley.ApplicationResources"/>
          <message-resources />元素屬性及其描述信息如下:
          屬  性    描  述
          Parameter    給定資源文件全名
          ClassName    定義處理消息資源的類名的全名,缺省是org.apache.struts.config.MessageResourcesConfig
          Factory    定義MessageResourcesFactory類的全名,缺省是org.apache.struts.util.property.MessageResourcesFacotry
          Key    定義綁定在這個資源包中的ServletContext的屬性主鍵,缺省值是Action.MESSAGES_KEY.
          Null    如果為true,則找不到消息key時,則返回null,缺省是true.
          例子:
          ① <message-resources parameter="wiley.ApplicationResources"/>
          ② <message-resources
              parameter="StorefrontMessageResources"
              null="false"/>
          <message-resources
              key="IMAGE_RESOURCE_KEY"
              parameter="StorefrontImageResources"
              null="false"/>

          注意:設定key的目的如下:
          <html:img altKey="navbar.home.image.alt" bundle="IMAGE_RESOURCE_KEY" pageKey="navbar.home.image" width="125" height="15" border="0"/>
          這里說明要到StorefrontImageResources.properties資源文件中找主鍵值是”navbar.home.image”所對應的值。
          這里StorefrontImageResources.properties的內容如下:
          ……
          navbar.home.image=/images/home.gif
          navbar.home.image.alt=Home
          ……
          此處navbar.home.image.alt說明的和<img alt=”Home”……/>一樣。


          九、    配置Plug-in
          配置Plug-in如下:
          <plug-in className="wiley.WileyPlugin"/>
          也可如下:
          <plug-in className="com.oreilly.struts.storefront.service.memory.StorefrontMemoryDatabasePlugIn">
            <set-property property="pathname" value="/WEB-INF/database.xml"/>
          </plug-in>

          下面是我現在的struts-config.xml文件:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">

          <struts-config>
            
          <form-beans >
              
          <form-bean name="OfferForm" type="com.neusoft.struts.form.OfferForm" />

            
          </form-beans>

            
          <global-exceptions />
            
          <global-forwards />
            
          <action-mappings >
              
          <action
                    
          attribute="OfferForm"
                    input
          ="/service/offerNew.jsp"
                    name
          ="OfferForm"
                    path
          ="/addOffer"
                    scope
          ="request"
                    type
          ="com.neusoft.struts.action.AddOfferAction">
                    
          <forward name="message" path="/service/message.jsp" />
                    
          <forward name="fail" path="/service/offerNew.jsp" />
              
          </action>
              
          <action path="/offerSearch"
                      input
          ="/service/offerSearch.jsp"
                      scope
          ="request" 
                      type
          ="com.neusoft.struts.action.OfferSearchAction">
                        
          <forward name="show" path="/service/offerSearch.jsp" />
              
          </action>
              
          <action  attribute="OfferForm"
                      name
          ="OfferForm"
                      path
          ="/offerUpdate"
                      input
          ="/service/offerUpdate.jsp"
                      scope
          ="request"
                      type 
          ="com.neusoft.struts.action.OfferUpdateAction" >
                      
          <forward name="message" path="/service/message.jsp"/>
                       
          <forward name="fail" path="/service/offerUpdate.jsp" />
              
          </action>
            
          </action-mappings>

            
          <message-resources parameter="com.neusoft.struts.ApplicationResources" />
          </struts-config>

          posted @ 2008-11-27 16:53 wesley1987 閱讀(1117) | 評論 (0)編輯 收藏

               摘要: 1.。JSP頁面中: ////////////數據顯示/////////////////////// 顯示 從數據庫查出的,放在 list<offer> 中的數據。 <c:forEach items="${requestScope.list}" var="offer">     <tr> &n...  閱讀全文

          posted @ 2008-11-27 13:34 wesley1987 閱讀(808) | 評論 (1)編輯 收藏

          2008年11月25日

          <!--
          /* 調用方法:
            <input onfocus="calendar()" name="s2" type="text" id="s2" style="width:100%;" />
          */
          var cal_Width = 180;//定義日歷顯示的寬度,至少140

          document.write("<div id='meizzCalendarLayer' style='position: absolute; z-index: 9999; width: " + (cal_Width+4).toString() + "px; height: 193px; display: none'>");
          document.write("<iframe name='meizzCalendarIframe' scrolling='no' frameborder='0' width='100%' height='100%'></iframe></div>");
          var WebCalendar = new WebCalendar();

          function document.onclick()
          {
              if(WebCalendar.eventSrc != window.event.srcElement) hiddenCalendar();
          }

          function WebCalendar() //初始化日歷的設置
          {
              this.regInfo    = "WEB Calendar ver 3.0 關閉的快捷鍵:[Esc]";
             
              this.dayShow    = 38;                       //定義頁面上要顯示的天數,不能小于35,或大于39
              this.daysMonth  = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
              this.day        = new Array(this.dayShow);            //定義日歷展示用的數組
              this.dayObj     = new Array(this.dayShow);            //定義日期展示控件數組
              this.dateStyle  = null;                     //保存格式化后日期數組
              this.objExport  = null;                     //日歷回傳的顯示控件
              this.eventSrc   = null;                     //日歷顯示的觸發控件
              this.inputDate  = null;                     //轉化外的輸入的日期(d/m/yyyy)
              this.thisYear   = new Date().getFullYear(); //定義年的變量的初始值
              this.thisMonth  = new Date().getMonth()+ 1; //定義月的變量的初始值
              this.thisDay    = new Date().getDate();     //定義日的變量的初始值
              this.today      = this.thisDay +"/"+ this.thisMonth +"/"+ this.thisYear;   //今天(d/m/yyyy)
              this.iframe     = window.frames("meizzCalendarIframe"); //日歷的 iframe 載體
              this.calendar   = getObjectById("meizzCalendarLayer");  //日歷的層
              this.dateReg    = "";           //日歷格式驗證的正則式

              this.yearFall   = 50;           //定義顯示的年份下拉框的年差值,如果今年是2000年,這里設置為50,就顯示1950-2050
              this.format     = "yyyy-mm-dd"; //回傳日期的格式
              this.timeShow   = false;        //是否返回時間
              this.drag       = true;         //是否允許拖動
              this.darkColor  = "#95B7F3";    //控件的暗色
              this.lightColor = "#FFFFFF";    //控件的亮色
              this.btnBgColor = "#E6E6FA";    //控件的按鈕背景色
              this.wordColor  = "#000080";    //控件的文字顏色
              this.wordDark   = "#DCDCDC";    //控件的暗文字顏色
              this.dayBgColor = "#F5F5FA";    //日期數字背景色
              this.todayColor = "#FF0000";    //今天在日歷上的標示背景色
              this.DarkBorder = "#D4D0C8";    //日期顯示的立體表達色
             
              this.yearOption = "";
              var yearNow = new Date().getFullYear();
              yearNow = (yearNow <= 1000)? 1000 : ((yearNow >= 9999)? 9999 : yearNow);
              var yearMin = (yearNow - this.yearFall >= 1000) ? yearNow - this.yearFall : 1000;
              var yearMax = (yearNow + this.yearFall <= 9999) ? yearNow + this.yearFall : 9999;
                  yearMin = (yearMax == 9999) ? yearMax-this.yearFall*2 : yearMin;
                  yearMax = (yearMin == 1000) ? yearMin+this.yearFall*2 : yearMax;
              for (var i=yearMin; i<=yearMax; i++) this.yearOption += "<option value='"+i+"'>"+i+"年</option>";
          }  

          function writeIframe()
          {
              var strIframe = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=gb2312'><style>"+
              "*{font-size: 12px; font-family: 宋體}"+
              ".bg{  color: "+ WebCalendar.lightColor +"; cursor: default; background-color: "+ WebCalendar.darkColor +";}"+
              "table#tableMain{ width: "+ (cal_Width+2).toString() +"px; height: 180px;}"+
              "table#tableWeek td{ width:14%;color: "+ WebCalendar.lightColor +";}"+
              "table#tableDay  td{ width:14%;font-weight: bold;}"+
              "td#meizzYearHead, td#meizzYearMonth{color: "+ WebCalendar.wordColor +"}"+
              ".out { text-align: center; border-top: 1px solid "+ WebCalendar.DarkBorder +"; border-left: 1px solid "+ WebCalendar.DarkBorder +";"+
              "border-right: 1px solid "+ WebCalendar.lightColor +"; border-bottom: 1px solid "+ WebCalendar.lightColor +";}"+
              ".over{ text-align: center; border-top: 1px solid #FFFFFF; border-left: 1px solid #FFFFFF;"+
              "border-bottom: 1px solid "+ WebCalendar.DarkBorder +"; border-right: 1px solid "+ WebCalendar.DarkBorder +"}"+
              "input{ border: 1px solid "+ WebCalendar.darkColor +"; padding-top: 1px; height: 18px; cursor: hand;"+
              "       color:"+ WebCalendar.wordColor +"; background-color: "+ WebCalendar.btnBgColor +"}"+
              "</style></head><body onselectstart='return false' style='margin: 0px' oncontextmenu='return false'><form name=meizz>";

              if (WebCalendar.drag){ strIframe += "<scr"+"ipt language=javascript>"+
              "var drag=false, cx=0, cy=0, o = parent.WebCalendar.calendar; function document.onmousemove(){"+
              "if(parent.WebCalendar.drag && drag){if(o.style.left=='')o.style.left=0; if(o.style.top=='')o.style.top=0;"+
              "o.style.left = parseInt(o.style.left) + window.event.clientX-cx;"+
              "o.style.top  = parseInt(o.style.top)  + window.event.clientY-cy;}}"+
              "function document.onkeydown(){ switch(window.event.keyCode){  case 27 : parent.hiddenCalendar(); break;"+
              "case 37 : parent.prevM(); break; case 38 : parent.prevY(); break; case 39 : parent.nextM(); break; case 40 : parent.nextY(); break;"+
              "case 84 : document.forms[0].today.click(); break;} " +
              "try{window.event.keyCode = 0; window.event.returnValue= false;}catch(ee){}}"+
              "function dragStart(){cx=window.event.clientX; cy=window.event.clientY; drag=true;}</scr"+"ipt>"}

              strIframe += "<table id=tableMain class=bg border=0 cellspacing=2 cellpadding=0>"+
              "<tr><td width='"+ cal_Width +"px' height='19px' bgcolor='"+ WebCalendar.lightColor +"'>"+
              "    <table width='"+ cal_Width +"px' id='tableHead' border='0' cellspacing='1' cellpadding='0'><tr align='center'>"+
              "    <td width='10%' height='19px' class='bg' title='向前翻 1 月 快捷鍵:←' style='cursor: hand' onclick='parent.prevM()'><b>&lt;</b></td>"+
              "    <td width='45%' id=meizzYearHead "+
              "        onmouseover='this.bgColor=parent.WebCalendar.darkColor; this.style.color=parent.WebCalendar.lightColor'"+
              "        onmouseout='this.bgColor=parent.WebCalendar.lightColor; this.style.color=parent.WebCalendar.wordColor'>" +
              "<select name=tmpYearSelect  onblur='parent.hiddenSelect(this)' style='width:100%;'"+
              "        onchange='parent.WebCalendar.thisYear =this.value; parent.hiddenSelect(this); parent.writeCalendar();'>";
             
          //    var yearNow = new Date().getFullYear();
          //    yearNow = (yearNow <= 1000)? 1000 : ((yearNow >= 9999)? 9999 : yearNow);
          //    var yearMin = (yearNow - WebCalendar.yearFall >= 1000) ? yearNow - WebCalendar.yearFall : 1000;
          //    var yearMax = (yearNow + WebCalendar.yearFall <= 9999) ? yearNow + WebCalendar.yearFall : 9999;
          //        yearMin = (yearMax == 9999) ? yearMax-WebCalendar.yearFall*2 : yearMin;
          //        yearMax = (yearMin == 1000) ? yearMin+WebCalendar.yearFall*2 : yearMax;
          //    for (var i=yearMin; i<=yearMax; i++) strIframe += "<option value='"+i+"'>"+i+"年</option>";

              strIframe += WebCalendar.yearOption + "</select>"+
              "</td>"+
              "    <td width='35%' id=meizzYearMonth "+
              "        onmouseover='this.bgColor=parent.WebCalendar.darkColor; this.style.color=parent.WebCalendar.lightColor'"+
              "        onmouseout='this.bgColor=parent.WebCalendar.lightColor; this.style.color=parent.WebCalendar.wordColor'>" +
              "<select name=tmpMonthSelect onblur='parent.hiddenSelect(this)' style='width:100%;'" +   
              "        onchange='parent.WebCalendar.thisMonth=this.value; parent.hiddenSelect(this); parent.writeCalendar();'>";
              for (var i=1; i<13; i++) strIframe += "<option value='"+i+"'>"+i+"月</option>";
              strIframe += "</select>"+
              "</td>"+
              "    <td width='10%' class=bg title='向后翻 1 月 快捷鍵:→' onclick='parent.nextM()' style='cursor: hand'><b>&gt;</b></td></tr></table>"+
              "</td></tr><tr><td height='20px'>"+
              "<table id=tableWeek border=1 width='"+ cal_Width +"px' cellpadding=0 cellspacing=0 ";
              if(WebCalendar.drag){strIframe += "onmousedown='dragStart()' onmouseup='drag=false' ";}
              strIframe += " borderColorLight='"+ WebCalendar.darkColor +"' borderColorDark='"+ WebCalendar.lightColor +"'>"+
              "    <tr align=center><td height='20px'>日</td><td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td></tr></table>"+
              "</td></tr><tr><td valign=top width='"+ cal_Width +"px' bgcolor='"+ WebCalendar.lightColor +"'>"+
              "    <table id=tableDay height='120px' width='"+ cal_Width +"px' border=0 cellspacing=1 cellpadding=0>";
                   for(var x=0; x<5; x++){
                     strIframe += "<tr>";
                     for(var y=0; y<7; y++)
                       strIframe += "<td class=out id='meizzDay"+ (x*7+y) +"'></td>";
                     strIframe += "</tr>";
                   }
                   strIframe += "<tr>";
                   for(var x=35; x<WebCalendar.dayShow; x++)
                     strIframe += "<td class=out id='meizzDay"+ x +"'></td>";
                   strIframe +="<td colspan="+(42-WebCalendar.dayShow).toString()+" class=out style='text-align:center;' title='"+ WebCalendar.regInfo +"'>" +
                   "<input style=' background-color: " + WebCalendar.btnBgColor +";cursor: hand; padding-top: 2px; width: 44%; height: 100%;' onfocus='this.blur()'"+
                   " type=button value='清空' onclick='parent.WebCalendar.objExport.value=\"\";parent.hiddenCalendar()'>" +
                   "&nbsp;" +
                   "<input style=' background-color: " + WebCalendar.btnBgColor +";cursor: hand; padding-top: 2px; width: 43%; height: 100%;' onfocus='this.blur()'"+
                   " type=button value='關閉' onclick='parent.hiddenCalendar()'>" +
                   "</td></tr></table>"+
              "</td></tr><tr><td height='20px' width='"+ cal_Width +"px' bgcolor='"+ WebCalendar.lightColor +"'>"+
              "    <table border=0 cellpadding=1 cellspacing=0 width='"+ cal_Width +"px'>"+
              "    <tr><td><input name=prevYear title='向前翻 1 年 快捷鍵:↑' onclick='parent.prevY()' type=button value='&lt;&lt;'"+
              "    onfocus='this.blur()' style='meizz:expression(this.disabled=parent.WebCalendar.thisYear==1000)'><input"+
              "    onfocus='this.blur()' name=prevMonth title='向前翻 1 月 快捷鍵:←' onclick='parent.prevM()' type=button value='&lt;&nbsp;'>"+
              "    </td><td align=center><input name=today type=button value='Today' onfocus='this.blur()' style='width: 50px;' title='當前日期 快捷鍵:T'"+
              "    onclick=\"parent.returnDate(new Date().getDate() +'/'+ (new Date().getMonth() +1) +'/'+ new Date().getFullYear())\">"+
              "    </td><td align=right><input title='向后翻 1 月 快捷鍵:→' name=nextMonth onclick='parent.nextM()' type=button value='&nbsp;&gt;'"+
              "    onfocus='this.blur()'><input name=nextYear title='向后翻 1 年 快捷鍵:↓' onclick='parent.nextY()' type=button value='&gt;&gt;'"+
              "    onfocus='this.blur()' style='meizz:expression(this.disabled=parent.WebCalendar.thisYear==9999)'></td></tr></table>"+
              "</td></tr><table></form></body></html>";
              with(WebCalendar.iframe)
              {
                  document.writeln(strIframe); document.close();
                  for(var i=0; i<WebCalendar.dayShow; i++)
                  {
                      WebCalendar.dayObj[i] = eval("meizzDay"+ i);
                      WebCalendar.dayObj[i].onmouseover = dayMouseOver;
                      WebCalendar.dayObj[i].onmouseout  = dayMouseOut;
                      WebCalendar.dayObj[i].onclick     = returnDate;
                  }
              }
          }

          function calendar() //主調函數
          {
              var e = window.event.srcElement;   writeIframe();
              var o = WebCalendar.calendar.style; WebCalendar.eventSrc = e;
           if (arguments.length == 0) WebCalendar.objExport = e;
              else WebCalendar.objExport = eval(arguments[0]);

              WebCalendar.iframe.tableWeek.style.cursor = WebCalendar.drag ? "move" : "default";
           var t = e.offsetTop,  h = e.clientHeight, l = e.offsetLeft, p = e.type;
           while (e = e.offsetParent){t += e.offsetTop; l += e.offsetLeft;}
              o.display = ""; WebCalendar.iframe.document.body.focus();
              var cw = WebCalendar.calendar.clientWidth, ch = WebCalendar.calendar.clientHeight;
              var dw = document.body.clientWidth, dl = document.body.scrollLeft, dt = document.body.scrollTop;
             
              if (document.body.clientHeight + dt - t - h >= ch) o.top = (p=="image")? t + h : t + h + 6;
              else o.top  = (t - dt < ch) ? ((p=="image")? t + h : t + h + 6) : t - ch;
              if (dw + dl - l >= cw) o.left = l; else o.left = (dw >= cw) ? dw - cw + dl : dl;

              if  (!WebCalendar.timeShow) WebCalendar.dateReg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/;
              else WebCalendar.dateReg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;

              try{
                  if (WebCalendar.objExport.value.trim() != ""){
                      WebCalendar.dateStyle = WebCalendar.objExport.value.trim().match(WebCalendar.dateReg);
                      if (WebCalendar.dateStyle == null)
                      {
                          WebCalendar.thisYear   = new Date().getFullYear();
                          WebCalendar.thisMonth  = new Date().getMonth()+ 1;
                          WebCalendar.thisDay    = new Date().getDate();
                          alert("原文本框里的日期有錯誤!\n可能與你定義的顯示時分秒有沖突!");
                          writeCalendar(); return false;
                      }
                      else
                      {
                          WebCalendar.thisYear   = parseInt(WebCalendar.dateStyle[1], 10);
                          WebCalendar.thisMonth  = parseInt(WebCalendar.dateStyle[3], 10);
                          WebCalendar.thisDay    = parseInt(WebCalendar.dateStyle[4], 10);
                          WebCalendar.inputDate  = parseInt(WebCalendar.thisDay, 10) +"/"+ parseInt(WebCalendar.thisMonth, 10) +"/"+
                          parseInt(WebCalendar.thisYear, 10); writeCalendar();
                      }
                  } else {
                    WebCalendar.thisYear   = new Date().getFullYear();
                    WebCalendar.thisMonth  = new Date().getMonth()+ 1;
                    WebCalendar.thisDay    = new Date().getDate();
                    writeCalendar();
                  }
              } catch(e) {
                WebCalendar.thisYear   = new Date().getFullYear();
                WebCalendar.thisMonth  = new Date().getMonth()+ 1;
                WebCalendar.thisDay    = new Date().getDate();
                writeCalendar();
              }
          }

          function funMonthSelect() //月份的下拉框
          {
              var m = isNaN(parseInt(WebCalendar.thisMonth, 10)) ? new Date().getMonth() + 1 : parseInt(WebCalendar.thisMonth);
              var e = WebCalendar.iframe.document.forms[0].tmpMonthSelect;
              e.value = m; //e.focus();
              //window.status = e.style.left;
          }

          function funYearSelect() //年份的下拉框
          {
              var e = WebCalendar.iframe.document.forms[0].tmpYearSelect;
              var y = isNaN(parseInt(WebCalendar.thisYear, 10)) ? new Date().getFullYear() : parseInt(WebCalendar.thisYear);
              e.value = y; //e.focus();
          //    if(e.value == "")
          //    {
          //      e.value = new Date().getFullYear();
          //      WebCalendar.thisYear = e.value;
          //    }
          }

          function prevM()  //往前翻月份
          {
              WebCalendar.thisDay = 1;
              if (WebCalendar.thisMonth==1)
              {
                  WebCalendar.thisYear--;
                  WebCalendar.thisMonth=13;
              }
              WebCalendar.thisMonth--; writeCalendar();
          }

          function nextM()  //往后翻月份
          {
              WebCalendar.thisDay = 1;
              if (WebCalendar.thisMonth==12)
              {
                  WebCalendar.thisYear++;
                  WebCalendar.thisMonth=0;
              }
              WebCalendar.thisMonth++; writeCalendar();
          }
          function prevY(){WebCalendar.thisDay = 1; WebCalendar.thisYear--; writeCalendar();}//往前翻 Year
          function nextY(){WebCalendar.thisDay = 1; WebCalendar.thisYear++; writeCalendar();}//往后翻 Year
          function hiddenSelect(e){
            //for(var i=e.options.length; i>-1; i--)e.options.remove(i); e.style.display="none";
          }
          function getObjectById(id){ if(document.all) return(eval("document.all."+ id)); return(eval(id)); }
          function hiddenCalendar(){getObjectById("meizzCalendarLayer").style.display = "none";};
          function appendZero(n){return(("00"+ n).substr(("00"+ n).length-2));}//日期自動補零程序
          function String.prototype.trim(){return this.replace(/(^\s*)|(\s*$)/g,"");}
          function dayMouseOver()
          {
              this.className = "over";
              this.style.backgroundColor = WebCalendar.darkColor;
              if(WebCalendar.day[this.id.substr(8)].split("/")[1] == WebCalendar.thisMonth)
              this.style.color = WebCalendar.lightColor;
          }
          function dayMouseOut()
          {
              this.className = "out"; var d = WebCalendar.day[this.id.substr(8)], a = d.split("/");
              this.style.removeAttribute('backgroundColor');
              if(a[1] == WebCalendar.thisMonth && d != WebCalendar.today)
              {
                  if(WebCalendar.dateStyle && a[0] == parseInt(WebCalendar.dateStyle[4], 10))
                  this.style.color = WebCalendar.lightColor;
                  this.style.color = WebCalendar.wordColor;
              }
          }
          function writeCalendar() //對日歷顯示的數據的處理程序
          {
              var y = WebCalendar.thisYear;
              var m = WebCalendar.thisMonth;
              var d = WebCalendar.thisDay;
              WebCalendar.daysMonth[1] = (0==y%4 && (y%100!=0 || y%400==0)) ? 29 : 28;
              if (!(y<=9999 && y >= 1000 && parseInt(m, 10)>0 && parseInt(m, 10)<13 && parseInt(d, 10)>0)){
                  alert("對不起,你輸入了錯誤的日期!");
                  WebCalendar.thisYear   = new Date().getFullYear();
                  WebCalendar.thisMonth  = new Date().getMonth()+ 1;
                  WebCalendar.thisDay    = new Date().getDate(); }
              y = WebCalendar.thisYear;
              m = WebCalendar.thisMonth;
              d = WebCalendar.thisDay;
             
              funYearSelect(parseInt(y, 10));
              funMonthSelect(parseInt(m,10));
              //WebCalendar.iframe.meizzYearHead.innerText  = y +" 年";
              //WebCalendar.iframe.meizzYearMonth.innerText = parseInt(m, 10) +" 月";
              WebCalendar.daysMonth[1] = (0==y%4 && (y%100!=0 || y%400==0)) ? 29 : 28; //閏年二月為29天
              var w = new Date(y, m-1, 1).getDay();
              var prevDays = m==1  ? WebCalendar.daysMonth[11] : WebCalendar.daysMonth[m-2];
              for(var i=(w-1); i>=0; i--) //這三個 for 循環為日歷賦數據源(數組 WebCalendar.day)格式是 d/m/yyyy
              {
                  WebCalendar.day[i] = prevDays +"/"+ (parseInt(m, 10)-1) +"/"+ y;
                  if(m==1) WebCalendar.day[i] = prevDays +"/"+ 12 +"/"+ (parseInt(y, 10)-1);
                  prevDays--;
              }
              for(var i=1; i<=WebCalendar.daysMonth[m-1]; i++) WebCalendar.day[i+w-1] = i +"/"+ m +"/"+ y;
              for(var i=1; i<WebCalendar.dayShow-w-WebCalendar.daysMonth[m-1]+1; i++)
              {
                  WebCalendar.day[WebCalendar.daysMonth[m-1]+w-1+i] = i +"/"+ (parseInt(m, 10)+1) +"/"+ y;
                  if(m==12) WebCalendar.day[WebCalendar.daysMonth[m-1]+w-1+i] = i +"/"+ 1 +"/"+ (parseInt(y, 10)+1);
              }
              for(var i=0; i<WebCalendar.dayShow; i++)    //這個循環是根據源數組寫到日歷里顯示
              {
                  var a = WebCalendar.day[i].split("/");
                  WebCalendar.dayObj[i].innerText    = a[0];
                  WebCalendar.dayObj[i].title        = a[2] +"-"+ appendZero(a[1]) +"-"+ appendZero(a[0]);
                  WebCalendar.dayObj[i].bgColor      = WebCalendar.dayBgColor;
                  WebCalendar.dayObj[i].style.color  = WebCalendar.wordColor;
                  if ((i<10 && parseInt(WebCalendar.day[i], 10)>20) || (i>27 && parseInt(WebCalendar.day[i], 10)<12))
                      WebCalendar.dayObj[i].style.color = WebCalendar.wordDark;
                  if (WebCalendar.inputDate==WebCalendar.day[i])    //設置輸入框里的日期在日歷上的顏色
                  {WebCalendar.dayObj[i].bgColor = WebCalendar.darkColor; WebCalendar.dayObj[i].style.color = WebCalendar.lightColor;}
                  if (WebCalendar.day[i] == WebCalendar.today)      //設置今天在日歷上反應出來的顏色
                  {WebCalendar.dayObj[i].bgColor = WebCalendar.todayColor; WebCalendar.dayObj[i].style.color = WebCalendar.lightColor;}
              }
          }
          function returnDate() //根據日期格式等返回用戶選定的日期
          {
              if(WebCalendar.objExport)
              {
                  var returnValue;
                  var a = (arguments.length==0) ? WebCalendar.day[this.id.substr(8)].split("/") : arguments[0].split("/");
                  var d = WebCalendar.format.match(/^(\w{4})(-|\/)(\w{1,2})\2(\w{1,2})$/);
                  if(d==null){alert("你設定的日期輸出格式不對!\r\n\r\n請重新定義 WebCalendar.format !"); return false;}
                  var flag = d[3].length==2 || d[4].length==2; //判斷返回的日期格式是否要補零
                  returnValue = flag ? a[2] +d[2]+ appendZero(a[1]) +d[2]+ appendZero(a[0]) : a[2] +d[2]+ a[1] +d[2]+ a[0];
                  if(WebCalendar.timeShow)
                  {
                      var h = new Date().getHours(), m = new Date().getMinutes(), s = new Date().getSeconds();
                      returnValue += flag ? " "+ appendZero(h) +":"+ appendZero(m) +":"+ appendZero(s) : " "+  h  +":"+ m +":"+ s;
                  }
                  WebCalendar.objExport.value = returnValue;
                  hiddenCalendar();
              }
          }
          //-->

          posted @ 2008-11-25 19:17 wesley1987 閱讀(803) | 評論 (1)編輯 收藏

          主站蜘蛛池模板: 泸水县| 洪雅县| 阜城县| 荣成市| 西昌市| 扎赉特旗| 台北县| 濉溪县| 白水县| 南郑县| 台东市| 镇赉县| 石家庄市| 永清县| 临城县| 怀来县| 嘉黎县| 楚雄市| 黎川县| 河间市| 乐业县| 理塘县| 青浦区| 武义县| 宝应县| 墨竹工卡县| 湘乡市| 武川县| 阳信县| 锦州市| 周口市| 庄浪县| 丽江市| 武川县| 马鞍山市| 兴文县| 三台县| 都江堰市| 宽甸| 南木林县| 股票|