JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java Application Framework » Spring  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 spring的使用問題…
peterpai

peterpai



發文: 103
積分: 1
於 2007-10-17 14:25 user profilesend a private message to usersend email to peterpaireply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
原問題在最下面,我修改一下,怕講的不清楚,順便再補幾個問題……

一、在web層,我知道可以用session傳遞資訊,例如使用者的帳號與密碼。那請當我的class不是web類時,如何取得存在session的資料?
或是有什麼更好的做法? 例如我使用acegi做認證,我想用aop做log的動作,但log時要記錄使用者名稱或ip等等資訊。那個log要怎麼取得
這些資料呢?

二、我使用spring時,因為是web application,所以透過以下的設定,可以取得bean的設定
1
2
3
4
5
6
7
8
9
10
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>    <!-- 指定acegi設定檔xml的位置-->
      /WEB-INF/applicationContext-acegi-security.xml  <!--acegi基本設定檔xml 含配合zk的特殊設定-->
      /WEB-INF/applicationContext-db-config.xml    <!-- dataSource設定 -->
      /WEB-INF/acegi-dir-security.xml          <!--acegi 目錄權限設定檔-->
      /WEB-INF/acegi-method-security.xml        <!--acegi 方法權限設定 -->
      /WEB-INF/spring-jdbc-config.xml          <!-- jdbc template相關設定 -->    
    </param-value>
  </context-param>


但是,如果我這樣子設定,在不啟動tomcat的情況下,我要寫程式並執行,那這些程式要怎麼讀取那些xml設定檔產生ApplicationContext呢?
我原本產生的方式如下:
1
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext((ServletContext) getDesktop().getWebApp().getNativeContext());


三、我想確認一下我的觀念,麻煩如錯糾正一下或提醒我該看什麼書或文件 Smile
1、有需要做transaction的,是不是應該是有好幾個相關的sql才需要?這一堆命令要就同時執行要不就不執行。commit與rollback就是解決這類問題的方法,
寫在commit與rollback中的就是transaction?這是不是只解決了acid裡一致性的問題?

2、多個SQL語句同時作用產生的問題是不是用隔離級別來解決?
另外,如果我是單人單緒的應用程式,就沒有設定隔離級別的需要?
那這解決了acid裡的哪些問題?還有什麼問題?要怎麼解決或注意什麼?

3、所以,若有一個DAO物件(假設都只有一條SQL語句),那它是不是沒必要去設定transaction?但除非單人單緒否則都應設定隔離級別?

以上,很感謝看我問題的人…… Smile

------------------------------------------------------------------------------------------
不好意思,我不知道題目這樣寫適不適合……

我目前是用spring+acegi+zk+log4j,我想做到的功能是,

當使用者因為要存取受acegi保護資源時,login的資料可以像以前寫在session裡一樣,可以保存住,這樣我log4j的log檔可以記錄時間、使用者做了某些事……

不知這樣做該如何著手?在哪裡要寫入使用者資料?寫到哪裡?在log4j怎麼記錄?

不好意思,可能是蠢問題,希望能給我一點方向,多謝!


peterpai edited on 2007-10-18 16:26
reply to postreply to post
作者 Re:spring+acegi+log4j web application如何記錄使用者資訊? [Re:peterpai]
roysiu





發文: 236
積分: 0
於 2007-10-18 14:16 user profilesend a private message to usersend email to roysiureply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
peterpai wrote:
不好意思,我不知道題目這樣寫適不適合……

我目前是用spring+acegi+zk+log4j,我想做到的功能是,

當使用者因為要存取受acegi保護資源時,login的資料可以像以前寫在session裡一樣,可以保存住,這樣我log4j的log檔可以記錄時間、使用者做了某些事……

不知這樣做該如何著手?在哪裡要寫入使用者資料?寫到哪裡?在log4j怎麼記錄?

不好意思,可能是蠢問題,希望能給我一點方向,多謝!

我早前也想試用 acegi的,因為聽聞它可以和 Captcha (即 Javaworld和 forum裏面的 challenge英文數字字母,不很知道其中文名)簡易地集成一起。但只學了個皮毛,不知是不是可以解決你的問題。

我知道的是 acegi 在 web認證上其實是 wrap了J2EE傳統的 Basic/Digest/Form/Cert認證,提供了一些類別 wrap了J2EE 的 Principal, Credential等類別。並可以用 SecurityHolder.getContext().getAuthentication() 來拿到 "Authentication" instance,那裏面應該有齊所有 login時的資料了 ... ...

我後來因為沒有心機看它一大堆config資料,所以放棄了。你們用 acegi來做什麼的,可否 share一下?

CakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCakeCake
peterpai wrote:
原問題在最下面,我修改一下,怕講的不清楚,順便再補幾個問題……


因為你改了,我也改一改 ... ... 我答我知道的東西吧 Big Smile


一、在web層,我知道可以用session傳遞資訊,例如使用者的帳號與密碼。那請當我的class不是web類時,如何取得存在session的資料?
或是有什麼更好的做法? 例如我使用acegi做認證,我想用aop做log的動作,但log時要記錄使用者名稱或ip等等資訊。那個log要怎麼取得
這些資料呢?


不熟 aop,幫不了你 Dead (但既然已經 weave了進 jar檔,到落 log時,應該和原來的 class在同一 classloader吧。用上述的方法不行嗎???不熟,不能很 sure地答你)


二、我使用spring時,因為是web application,所以透過以下的設定,可以取得bean的設定

如果是 jdk1.5以上的話有一個 叫 javax.xml.xpath.XPath ,真接 parse web.xml好了 ... ... (如果有用 jdom的話,它那個 api更簡單)


1、有需要做transaction的,是不是應該是有好幾個相關的sql才需要?這一堆命令要就同時執行要不就不執行。commit與rollback就是解決這類問題的方法,
寫在commit與rollback中的就是transaction?這是不是只解決了acid裡一致性的問題?

"同時執行要不就不執行"... ... 這已經是很難 grantutee的了,那是傳統寫 program的同步 (synchronize)問題。「不是」有好幾個相關的sql才需要,而是有 update/insert/delete就需要 (這個很多人也攪錯的Dead)。沒錯,commit與rollback 就是 handle這些問題而 expose出來的 API。對業務很著緊的 Software Developer稱分 commit/rollback的時機叫作 "Demarcate Transaction" (分割 tx)。


2、多個SQL語句同時作用產生的問題是不是用隔離級別來解決?
另外,如果我是單人單緒的應用程式,就沒有設定隔離級別的需要?
那這解決了acid裡的哪些問題?還有什麼問題?要怎麼解決或注意什麼?

隔離級別是用作解決同一條tx裏多條sql,query不穏定的問題 --- 但注意﹗加了它只是解決了一些眼見不到的tx問題。而不是解決了 workflow或 pageflow level的transaction問題。


3、所以,若有一個DAO物件(假設都只有一條SQL語句),那它是不是沒必要去設定transaction?但除非單人單緒否則都應設定隔離級別?

因為上述原因,這個 prove是不能成立的,但可惜的是一般 software友也會是這樣認為的,那就是 biz系統裏面常發生的 tx問題的根源了... ... Dead。Correct OR Not通常只是一句與兩句之差,正所謂﹕「差之鴻毛,謬若千里」 (sorry 錯別字 「差之毫毛,謬之千里」).... 很玄吧 Big Smile


roysiu edited on 2007-10-19 09:37
reply to postreply to post
作者 Re:spring的使用問題… [Re:peterpai]
peterpai

peterpai



發文: 103
積分: 1
於 2007-10-18 20:19 user profilesend a private message to usersend email to peterpaireply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
感謝roysiu 的回覆,有些小弟不懂的部份,還昐您指點!

1、 javax.xml.xpath.XPath可以用在這上面嗎? 不好意思我還沒試,只是我想,要看懂web.xml,然後再從web.xml裡找到其它設定檔,應該…要和spring有點關係才辦得到吧! 所以您寫個javax.....我就覺得還滿神奇的,有空我會試!

2、您回答transaction的問題時寫到:「不是」有好幾個相關的sql才需要,而是有 update/insert/delete就需要
這……我還真不懂,因為我原本的想法是要有好幾個sql才需要…
照您的說法,假如我insert資料到一個table裡,這不成功本來就失效啦…還要rollback做什麼呢?除非……會發生table裡有5個欄位結果只寫到3個的事情會發生……

3、隔離級別..的部份,您能不能講白話一點,或多說一點…(如果方便的話)
我認真的想了一下您說的。麻煩您確認一下我的想法對不對還有多回答我一些問題。 Smile

小弟沒上過學…… Smile
我不是本科系的……所以看到太基本的問題,也請見諒了……


reply to postreply to post
作者 Re:spring的使用問題… [Re:peterpai]
roysiu





發文: 236
積分: 0
於 2007-10-18 22:46 user profilesend a private message to usersend email to roysiureply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
peterpai wrote:
1、 javax.xml.xpath.XPath可以用在這上面嗎? 不好意思我還沒試,只是我想,要看懂web.xml,然後再從web.xml裡找到其它設定檔,應該…要和spring有點關係才辦得到吧! 所以您寫個javax.....我就覺得還滿神奇的,有空我會試!

我是見能夠用得 spring+acegi,應該不會不明白的吧 (我一向寫程式的主張是 "沒有九成懂,決不會使用")。所以跳了步來說,步驟應該是﹕

(1) 用 XPath parse "web.xml",拿了spring 的 xml檔 path
(2) 有了檔名了,便可用傳統的 spring方法來拿 datasource, ... ...

關於 XPath的 document在這兒可以找到
http://www.onjava.com/pub/a/onjava/2005/01/12/xpath.html
(個人認為 Java裏面最好用的 external libraries是 commons-lang, beanutils, jdom, commons-digester, velocity 等。當能夠熟用它們以後,用java寫出來的程式會變得充實很多 ... ... 就因為有這些前人寫下的强勁 libraries,我才會想繼續進深 java,「不重複輪子」呢﹗前一陣子,和人討論,記下這句話了 ... ... 本身如果什麼 opensource也不用的話,java 是會比寫 C#等慢的)

peterpai wrote:
2、您回答transaction的問題時寫到:「不是」有好幾個相關的sql才需要,而是有 update/insert/delete就需要
這……我還真不懂,因為我原本的想法是要有好幾個sql才需要…
照您的說法,假如我insert資料到一個table裡,這不成功本來就失效啦…還要rollback做什麼呢?除非……會發生table裡有5個欄位結果只寫到3個的事情會發生……

但如果A 用戶正 delete all, 而 B用戶正 insert 呢?同一table,兩個也是成功。A 便會發覺他沒有 delete all 了 ... ...

peterpai wrote:
3、隔離級別..的部份,您能不能講白話一點,或多說一點…(如果方便的話)
我認真的想了一下您說的。麻煩您確認一下我的想法對不對還有多回答我一些問題。 Smile

說白一點,隔離級別就是為了解決四種情況 (但是只是隔離由開 connection至commit和 rollback中間的處理)﹕丟失更新、dirty read, unrepeatable read 和 phantom read。詳細描述 到 wiki 找一找就會找到的了 ... ...


roysiu edited on 2007-10-18 23:14
reply to postreply to post
作者 Re:spring的使用問題… [Re:peterpai]
peterpai

peterpai



發文: 103
積分: 1
於 2007-10-20 15:28 user profilesend a private message to usersend email to peterpaireply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
關於第一個問題的自問自答…
(我只單純的考慮我的環境的解法,也就是zk、acegi……)

1、LogBeforeAdvice如下的寫法可以取得使用者帳號與ip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package peter.commonProject.demo;
 
import java.lang.reflect.Method;
 
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice ;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.Sessions;
 
public class LogBeforeAdvice implements MethodBeforeAdvice {
  private Logger logger = 
        Logger.getLogger(this.getClass().getName()); 
 
public void before(Method method, Object[] args, 
                 Object target) throws Throwable { 
  Session session = Sessions.getCurrent();
  
    logger.log(Level.INFO,"method starts..." + method+session.getClientAddr()+session.getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY)); 
    
} 
}


2、目前的想法是,繼承zk windows的class負責動態元件與controller的功能,範例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package peter.commonProject.demo;
 
import javax.servlet.ServletContext;
 
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.zkoss.zul.Window;
 
@SuppressWarnings("serial")
public class TestAOPWnd extends Window {
public void test(){
  
  ApplicationContext ctx = WebApplicationContextUtils
  .getRequiredWebApplicationContext((ServletContext) getDesktop()
      .getWebApp().getNativeContext());
  
  IHello helloProxy = 
        (IHello) ctx.getBean("helloProxy"); 
    helloProxy.hello("Justin"); 
}
}
 


執行結果如下:
1
2
2007-10-20 15:20:42,671 [Thread-7] INFO  peter.commonProject.demo.LogBeforeAdvice - method starts...public abstract void peter.commonProject.demo.IHello.hello(java.lang.String)127.0.0.1peter
Hello, Justin


3、aop的例子,程式碼與設定完全照良格葛的文章,除了LogBeforeAdvice加了一些東西。

4、測試成功,已可達到我需求的功能,但目前腦袋不清醒中,等清醒一點再思考這樣做是否有什麼缺點……


peterpai edited on 2007-10-20 15:31
reply to postreply to post
作者 Re:spring的使用問題… [Re:peterpai]
roysiu





發文: 236
積分: 0
於 2007-10-21 22:05 user profilesend a private message to usersend email to roysiureply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
peterpai wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package peter.commonProject.demo;
 
import java.lang.reflect.Method;
 
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice ;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.Sessions;
 
public class LogBeforeAdvice implements MethodBeforeAdvice {
  private Logger logger = 
        Logger.getLogger(this.getClass().getName()); 
 
public void before(Method method, Object[] args, 
                 Object target) throws Throwable { 
  Session session = Sessions.getCurrent();
  
    logger.log(Level.INFO,"method starts..." + method+session.getClientAddr()+session.getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY)); 
    
} 
}


給你一些關於編程上的建議 ... ...

(1) 我想你漏了 care沒有 ACEGI_SECURITY_LAST_USERNAME_KEY 在 session的情況,

(2) 你確認只需要 log登入的使用者名稱而不需要理會他用什麼身份登入?上述方法真的幫不到你?(或用 attribute "ACEGI_SECURITY_CONTEXT" 來拿)

(3) 好像將 "session.getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY)" 放在一個共享的地方會比較好。如
"SecurityContextHolder.getContext().getAuthentication()" 就是一個比較好的編程 approach ... ...

(4) 其實還有的 ... ... Logger應該 pass 進 Class,用 common-logging 等 ... ...


roysiu edited on 2007-10-21 23:05
reply to postreply to post
作者 Re:spring的使用問題… [Re:peterpai]
peterpai

peterpai



發文: 103
積分: 1
於 2007-10-22 09:47 user profilesend a private message to usersend email to peterpaireply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
感謝roysiu 的回覆!

1、我不知道要如何care沒有 ACEGI_SECURITY_LAST_USERNAME_KEY 在 session的情況。目前看到的狀況是,如果使用者沒登入的話,username是null。
程式不會出錯…null…我可以接受,反正null就代表這個程式不用登入就可以用…

2、謝謝您的建議,我變更log記錄的資訊如下:
1
 logger.log(Level.INFO,"method starts..." + method+session.getClientAddr()+session.getAttribute("ACEGI_SECURITY_CONTEXT")); 

這樣子寫,ip、登入的帳號與身份都會出來… 雖然不知道這是不是和您提的一樣,但也多解決了問題,感謝!

3、4兩點,我…看不懂…至少現在可以work,先這樣…回頭我再仔細研究!

總之,感謝您這一系列的指點,雖然小弟不能完全明白您的意思,…希望以後可以看得懂。


reply to postreply to post
» JWorld@TW »  Java Application Framework » Spring

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8