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

          2010年7月29日

          [ERROR] 07-29 11:23 - The /WEB-INF/web.xml was not found.  (ActionServlet.java:1787)
          java.net.ConnectException: Connection timed out: connect

          原web.xml頭部:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
          <web-app>




            <servlet>
              <servlet-name>action</servlet-name>
              <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>


          修改為
          <?xml version="1.0" encoding="UTF-8"?>
          <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
              xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">




            
          <servlet>
              
          <servlet-name>action</servlet-name>
              
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

          posted @ 2010-07-29 11:23 wesley1987 閱讀(1511) | 評論 (0)編輯 收藏

          2010年7月28日


          在tomcat等容器中發(fā)布帶velocity的應(yīng)用時, 出現(xiàn) org.apache.velocity.exception.ResourceNotFoundException : Unable to find resource ...vm  的解決辦法:

          配置文件 velocity.properties 中, 如果有
          resource.loader = file

          file
          .resource.loader.description = Velocity File Resource Loader
          file
          .resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
          file
          .resource.loader.path = .
          file
          .resource.loader.cache = false
          file
          .resource.loader.modificationCheckInterval = 2

          這段, 全部注釋掉即可.

          若沒有, 就在配置里寫上以上內(nèi)容, 并更改第三項為

          file.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader

          posted @ 2010-07-28 15:35 wesley1987 閱讀(14184) | 評論 (1)編輯 收藏

          1。指定velocity.properties文件,  默認(rèn)路徑為 WEB-INF/velocity.properties 也可自定義路徑, 在web.xml中
                <servlet>
                  
          <servlet-name>velocity</servlet-name>
                  
          <servlet-class>org.apache.velocity.tools.view.servlet.VelocityLayoutServlet</servlet-class>
                  
          <init-param>
                      
          <param-name>org.apache.velocity.properties</param-name>
                      
          <param-value>/WEB-INF/config/velocity.properties</param-value>
                  
          </init-param>
                  
          <init-param>
                      
          <param-name>org.apache.velocity.toolbox</param-name>
                      
          <param-value>/WEB-INF/config/velocity-toolbox.xml</param-value>
                  
          </init-param>
                  
          <load-on-startup>5</load-on-startup>
                
          </servlet>
          注意 load-on-startup 需要配置且靠后, 否則啟動時看不到日志.

          2。在velocity.properties中配置日程相關(guān)參數(shù):
          #----------------------------------------------------------------------------
          #  default LogSystem to use: default: AvalonLogSystem
          #----------------------------------------------------------------------------


          runtime
          .log.logsystem.class = org.apache.velocity.runtime.log.SimpleLog4JLogSystem

          runtime
          .log.logsystem.log4j.category = velocity_log

          #----------------------------------------------------------------------------
          # This controls if Runtime.error(), info() and warn() messages include the
          # whole stack trace. The last property controls whether invalid references
          # are logged.
          #----------------------------------------------------------------------------


          runtime
          .log.error.stacktrace = false
          runtime
          .log.warn.stacktrace = false
          runtime
          .log.info.stacktrace = false
          runtime
          .log.invalid.reference = true


          3\ 配置log4j.properties,  具體配置意義請參看log4j配置相關(guān)文檔
          log4j.rootLogger=INFO,CONSOLE,FILE
          log4j
          .logger.velocity_log=INFO,CONSOLE,VELOCITY
          log4j
          .addivity.org.apache=true

          log4j
          .appender.CONSOLE=org.apache.log4j.ConsoleAppender
          log4j
          .appender.CONSOLE.Threshold=WARN
          log4j
          .appender.CONSOLE.Target=System.out
          log4j
          .appender.CONSOLE.Encoding=GBK
          log4j
          .appender.CONSOLE.layout=org.apache.log4j.PatternLayout
          log4j
          .appender.CONSOLE.layout.ConversionPattern=[%-4p] %d{MM-dd HH:mm} - %m  %n

          log4j
          .appender.VELOCITY=org.apache.log4j.FileAppender
          log4j
          .appender.VELOCITY.File=E:/workspace/dwrt/WebRoot/log/velocity.log
          log4j
          .appender.VELOCITY.Append=false
          log4j
          .appender.VELOCITY.Encoding=GBK
          log4j
          .appender.VELOCITY.layout=org.apache.log4j.PatternLayout
          log4j
          .appender.VELOCITY.layout.ConversionPattern=[%-4p] %d{MM-dd HH:mm} - %m  %n

          posted @ 2010-07-28 11:39 wesley1987 閱讀(2475) | 評論 (0)編輯 收藏

          2010年7月7日

          select COUNT(*) from table t WHERE t.col <> '3'


          SELECT COUNT(*) FROM table t WHERE t.col NOT IN
          (select t.col from table t WHERE t.col= '3')

          以上兩句SQL的執(zhí)行結(jié)果不同, 因為 <> 在排除3的同時, 將null也排除了,
          所以當(dāng)比較字段含null時,第一句將比第二句的結(jié)果少.

          當(dāng)然第二句從效率上來說不是一個好的寫法, 這樣寫只是為了理解, 在第一句后面, 加上 or t.col is null 應(yīng)該就等效了.

          posted @ 2010-07-07 10:17 wesley1987 閱讀(7305) | 評論 (1)編輯 收藏

          在js中寫了個替換字符的句子, 然后才知道原來js沒有replaceAll方法, 就是說用replace的話, 他自會替換一次.

          自定義replaceAll方法,
          String.prototype.replaceAll  = function(s1,s2){    
                  return this.replace(new RegExp(s1,"gm"),s2);   
          }  

          gm     g=global, m=multiLine  , 

          或直接 string = string..replace(new RegExp(s1,"gm"),s2);   

          posted @ 2010-07-07 09:44 wesley1987 閱讀(1076) | 評論 (0)編輯 收藏

          2009年7月27日

          在使用DispatchAction時出現(xiàn)了這個問題,從這句話分析,就是沒有在指定的類中,找到對應(yīng)的方法。

          先說結(jié)論: 在Action中定義的方法(要在參數(shù)中使用的方法),參數(shù)一定要固定為
          (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response )

          --------------------------------
          這種錯誤,一般在保證所有路徑的拼寫都正確的情況下應(yīng)該就能避免,

          那接著分析一下,struts是如何從jsp一步步找到這個方法呢?


          1 頁面上 action的路徑,以及對應(yīng)的struts配置文件中定義的parameter的參數(shù)名(我這叫method)屬性值,這個屬性值應(yīng)對應(yīng)著 Action類的方法名。

          2 確認(rèn)了以上路徑都正確的情況下,考慮到DispatchAction對應(yīng)“方法”的方式,發(fā)現(xiàn)原來是方法多了一個參數(shù)。

          順便看了下DispatchAction源代碼,看到里面找方法的時候,用的是
           method = clazz.getMethod(name, types);
          其中
          clazz = getClass();
          types = (new Class[] {
                      org.apache.struts.action.ActionMapping.class,  org.apache.struts.action.ActionForm.class,  javax.servlet.http.HttpServletRequest.class,  javax.servlet.http.HttpServletResponse.class
                  });

          就是說,DispatchAction只會將參數(shù)固定為以上4中的函數(shù)作為控制器方法使用。

          posted @ 2009-07-27 21:13 wesley1987 閱讀(4248) | 評論 (2)編輯 收藏

          2009年4月21日

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

           Spring Security使用一組過濾器鏈來對用戶進(jìn)行身份驗證和授權(quán)。首先,在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實現(xiàn)了Filter接口,它通過調(diào)用WebapplicationContextUtils類的getWebApplicationnContext(servletContext)方法來獲取Spring的應(yīng)用上下文句柄,并通過getBean(beanName)方法來獲取Spring受管Bean的對象,即這里targetClass參數(shù)配置的Bean,并通過調(diào)用FilterChain Proxy的init()方法來啟動Spring Security過濾器鏈進(jìn)行各種身份驗證和授權(quán)服務(wù)(FilterChainProxy類也是實現(xiàn)了Filter接口),從而將過濾功能委托給Spring的FilterChainProxy受管Bean(它維護(hù)著一個處理驗證和授權(quán)的過濾器列表,列表中的過濾器按照一定的順序執(zhí)行并完成認(rèn)證過程),這樣即簡化了web.xml文件的配置,又能充分利用 Spring的IoC功能來完成這些過濾器執(zhí)行所需要的其它資源的注入。

                  當(dāng)用戶發(fā)出請求,過濾器需要根據(jù)web.xml配置的請求映射地址來攔截用戶請求,這時Spring Security開始工作,它會驗證你的身份以及當(dāng)前請求的資源是否與你擁有的權(quán)限相符,從而達(dá)到保護(hù)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默認(rèn)的進(jìn)行表單驗證的過濾地址,你也可以修改為別的名稱,但是需要和
          applicationContext-security.xml中相對應(yīng),當(dāng)然還會涉及到其它一些默認(rèn)值(可能是一個成員變量,也可能是別的請
          求地址),在下文我們將看到,建議你在閱讀此文的同時,應(yīng)該參照Spring Security項目的源代碼,便于你更好的理解。


          3 配置applicationContext-security.xml

              3.1 FilterChainProxy過濾器鏈

              FilterChainProxy會按順序來調(diào)用一組filter,使這些filter即能完成驗證授權(quán)的本質(zhì)工作,又能享用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在匹配之前必須先轉(zhuǎn)為小寫,PATTERN_TYPE_APACHE_ANT 定義了使用Apache ant的匹配模式,/**定義的將等號后面的過濾器應(yīng)用在那些URL上,這里使用全部URL過濾,每個過濾器之間都適用逗號分隔,它們按照一定的順序排列。

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

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

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

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

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

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

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

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

              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            <!-- 實現(xiàn)了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 閱讀(618) | 評論 (0)編輯 收藏

          2008年12月23日

           

                            項目實訓(xùn)心得

                       在這一個多月的項目實訓(xùn)過程,我感到是我專業(yè)學(xué)習(xí)中收獲非常大的一個月。在這個月里,我體驗到了團(tuán)隊合作的經(jīng)驗,編程過程中的樂趣,以及將學(xué)習(xí)應(yīng)用到實際、從實踐中學(xué)習(xí)的豐收感。

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

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

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

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

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

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

                         

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

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

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

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

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

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

              //文采太爛, 結(jié)尾的感慨段就不發(fā)了

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

          2008年12月15日

          今天一個詭異的問題弄了我半天,最后發(fā)現(xiàn)原因如下:

          在HTML的head中 引入外部script:
                  <script src="<%=path%>/js/service.js" type="text/javascript" ></script>
          之后又寫內(nèi)部script (內(nèi)容無關(guān))
          <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"  />變了下結(jié)尾
          引入的外部script任然好用,但是下面的內(nèi)部script就完全不執(zhí)行。并伴隨很多奇怪的顯示效果。

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

          轉(zhuǎn)自網(wǎng)上的一篇很詳細(xì)的關(guān)于servlet中各種出現(xiàn)亂碼的問題即解決方案:
          http://www.diybl.com/course/3_program/java/javajs/200829/99730.html

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

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

          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中進(jìn)行部署
          分別是:filter和filter-mapping。filter元素向系統(tǒng)注冊一個過濾對象,filter-mapping元素指定該過濾對象所應(yīng)用的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  這是一個必需的元素,它指定過濾器實現(xiàn)類的完全限定名。
           : init-param  這是一個可選的元素,它定義可利用FilterConfig的getInitParameter方法讀取的初始化參數(shù)。單個過濾器元素可包含多個init-param元素。
          2.filter-mapping元素
            filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三個可能的子元素::
            filter-name 這個必需的元素必須與用filter元素聲明時給予過濾器的名稱相匹配。
            url-pattern  此元素聲明一個以斜杠(/)開始的模式,它指定過濾器應(yīng)用的URL。所有filter-mapping元素中必須提供url-pattern或servlet-name。但不能對單個filter-mapping元素提供多個url-pattern元素項。如果希望過濾器適用于多個模式,可重復(fù)整個filter-mapping元素。
          :servlet-name  此元素給出一個名稱,此名稱必須與利用servlet元素給予servlet或JSP頁面的名稱相匹配。不能給單個filter-mapping元素提供多個servlet-name元素項。如果希望過濾器適合于多個servlet名,可重復(fù)這個filter-mapping元素。

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

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

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

          3.在web.xml中進(jìn)行部署
          在web.xml的過濾器-編輯器中選擇:servlet 映射 - 添加 - Faces Servlet
          會在web.xml中產(chǎn)生如下代碼:
          <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轉(zhuǎn)成Java文件時的編碼問題,默認(rèn)的話有的服務(wù)器是ISO-8859-1,如果一個JSP中直接輸入了中文,Jsp把它當(dāng)作ISO8859-1來處理是肯定有問題的,這一點,我們可以通過查看Jasper所生成的Java中間文件來確認(rèn)
          (二)    當(dāng)用Request對象獲取客戶提交的漢字代碼的時候,會出現(xiàn)亂碼:
          解決的辦法是:要配置一個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>

          如果你的還是出現(xiàn)這種情況的話你就往下看看是不是你出現(xiàn)了第四中情況,你的Form提交的數(shù)據(jù)是不是用get提交的,一般來說用post提交的話是沒有問題的,如果是的話,你就看看第四中解決的辦法。
          還有就是對含有漢字字符的信息進(jìn)行處理,處理的代碼是:
          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;
           }
          }
          你也可以在直接的轉(zhuǎn)換,首先你將獲取的字符串用ISO-8859-1進(jìn)行編碼,然后將這個編碼存放到一個字節(jié)數(shù)組中,然后將這個數(shù)組轉(zhuǎn)化成字符串對象就可以了,例如:
          String str=request.getParameter(“girl”);
          Byte B[]=str.getBytes(“ISO-8859-1”);
          Str=new String(B);
          通過上述轉(zhuǎn)換的話,提交的任何信息都能正確的顯示。
          (三)    在Formget請求在服務(wù)端用request. getParameter(“name”)時返回的是亂碼;按tomcat的做法設(shè)置Filter也沒有用或者用request.setCharacterEncoding("GBK");也不管用問題是出在處理參數(shù)傳遞的方法上:如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法進(jìn)行處理的話前面即使是寫了:
          request.setCharacterEncoding("GBK");
          response.setContentType("text/html;charset=GBK");
          也是不起作用的,返回的中文還是亂碼!!!如果把這個函數(shù)改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。
          同樣,在用兩個JSP頁面處理表單輸入之所以能顯示中文是因為用的是post方法傳遞的,改成get方法依舊不行。
          由此可見在servlet中用doGet()方法或是在JSP中用get方法進(jìn)行處理要注意。這畢竟涉及到要通過瀏覽器傳遞參數(shù)信息,很有可能引起常用字符集的沖突或是不匹配。
          解決的辦法是:
          1) 打開tomcat的server.xml文件,找到區(qū)塊,加入如下一行:
          URIEncoding=”GBK”
          完整的應(yīng)如下:
          <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中也是要出現(xiàn)亂碼的情況,如果不行的話就換別的字符集。
          (四)    JSP頁面上有中文,按鈕上面也有中文,但是通過服務(wù)器查看頁面的時候出現(xiàn)亂碼:
               解決的辦法是:首先在JSP文件中不應(yīng)該直接包含本地化的消息文本,而是應(yīng)該通過<bean:message>標(biāo)簽從Resource Bundle中獲得文本。應(yīng)該把你的中文文本放到Application.properties文件中,這個文件放在WEB-INF/classes/*下,例如我在頁面里有姓名,年齡兩個label,我首先就是要建一個Application.properties,里面的內(nèi)容應(yīng)該是name=”姓名” age=”年齡”,然后我把這個文件放到WEB-INF/classes/properties/下,接下來根據(jù)Application.properties文件,對他進(jìn)行編碼轉(zhuǎn)化,創(chuàng)建一個中文資源文件,假定名字是Application_cn.properties。在JDK中提供了native2ascii命令,他能夠?qū)崿F(xiàn)字符編碼的轉(zhuǎn)換。在DOS環(huán)境中找到你放置Application.properties的這個文件的目錄,在DOS環(huán)境中執(zhí)行一下命令,將生成按GBK編碼的中文資源文件Application_cn.properties:native2ascii ?encoding gbk Application.properties Application_cn.properties執(zhí)行以上命令以后將生成如下內(nèi)容的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”>,這樣的化在頁面上出現(xiàn)的時候就會出現(xiàn)中文的姓名,年齡這個也是一樣,按鈕上漢字的處理也是同樣的。
          (五)    寫入到數(shù)據(jù)庫是亂碼:
          解決的方法:要配置一個filter,也就是一個Servelet的過濾器,代碼如同第二種時候一樣。
          如果你是通過JDBC直接鏈接數(shù)據(jù)庫的時候,配置的代碼如下:jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK,這樣保證到數(shù)據(jù)庫中的代碼是不是亂碼。
          如果你是通過數(shù)據(jù)源鏈接的化你不能按照這樣的寫法了,首先你就要寫在配置文件中,在tomcat 5.0.19中配置數(shù)據(jù)源的地方是在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直接鏈接的時候是有區(qū)別的,如果你是配置正確的化,當(dāng)你輸入中文的時候到數(shù)據(jù)庫中就是中文了,有一點要注意的是你在顯示數(shù)據(jù)的頁面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>這行代碼的。需要注意的是有的前臺的人員在寫代碼的是后用Dreamver寫的,寫了一個Form的時候把他改成了一個jsp,這樣有一個地方要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他該過來,因為在jsp的提交的過程中緊緊就是POST和GET兩種方式,但是這兩種方式提交的代碼在編碼方面還是有很大不同的,這個在后面的地方進(jìn)行說明.


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

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

          主站蜘蛛池模板: 榕江县| 汶川县| 曲阜市| 西乡县| 舟曲县| 梨树县| 化州市| 文安县| 太仆寺旗| 桂平市| 辛集市| 长宁区| 项城市| 江门市| 宁津县| 铅山县| 敦化市| 娱乐| 镇康县| 宁陵县| 湘潭县| 临武县| 兰西县| 屯留县| 西安市| 广饶县| 丰宁| 吴忠市| 昌宁县| 泰州市| 贺州市| 宿州市| 华宁县| 临安市| 雅安市| 高邑县| 西城区| 武平县| 卫辉市| 湘潭县| 岑溪市|