2013-04-30 18 views
3

我有一個Session-Scope Bean LoginPlaintext,它不能是可序列化的。Spring的DI不是瞬態的,不可序列化但是日誌NSE

我有一個必須可序列化的會話範圍Bean LoginMD5Salted

兩者共享不是Serializable的接口Login(因爲LoginPlaintext必須不可序列化)!

我AppConfig.java看起來是這樣的:

public class AppConfig 
    ... 
    Login loginData(ServletRequest request){ 
     if(request.getParameter('useMD5')!=null){ 
     return new LoginMD5Salted(); 
     } 
     return new LoginPlaintext(); 
    } 
} 

我PermissionBean的.java看起來是這樣的:

public class PermissionBean implements Serializable{ 
    @Autowired 
    Login loginData; 
} 

我LoginPlaintext看起來是這樣的:

public class LoginPlaintext implements Login{ 
    String plainTextPassword; 
    .... 
} 

我LoginMD5Salted外觀像這樣:

public class LoginMD5Salted implements Login, Serializable{ 
    private static final long serialVersionUID = 2742674005972067910L; 
    // not sure Upcase/Lowcase 
    String MD5PasswordSalted; 
} 

如果會話已被序列化:豆類LoginPlaintext將不會被持久化。如果會話被反序列化,所有其他值都被反序列化,但解碼器LoginPlaintext會拋出一個NotSerializableException,確定。

如果該會話被序列化:豆LoginMD5Salted將保持良好。如果會話被反序列化,所有的值都被反序列化,即使是LoginMD5Salted也沒有任何問題。 問題:

  1. 我該如何防止只有類LoginPlaintext的日誌消息?
  2. 如果LoginPlaintext無法通過重新激活進行反序列化,AppConfig的loginData()方法是否會再次被調用?
+0

請問您可以詳細說明一下 我該如何防止FooImpl1類的日誌消息? 如果FooImpl1無法通過重新激活進行反序列化,那麼AppConfig的foo()方法會再次被調用嗎? – 2013-05-02 15:42:17

+0

1.在服務器啓動時,服務器上出現第一個帶有舊Session-ID-Cookie的請求:FooImpl1不能被反序列化,並且會記錄一個Exception,雖然它不是一個錯誤!如何防止非錯誤異常的記錄。 2.因此'@ Autowire'應該調用foo()來產生新的FooImpl2/FooImpl1。 – 2013-05-03 07:45:06

+0

您能否提供有關您的組件的更多信息?類似於Foo對象的類聲明(成員迫使它保持不可序列化),無論Foo是會話屬性的一部分,還是直接綁定(您在哪裏使用@Autowired),何時何地Foo被初始化(您對AppConfig的調用.foo())等。 – 2013-05-06 08:57:22

回答

1

如果不是勢在必行不實現序列化,你可以只是使它序列化,並覆蓋LoginPlaintext的序列化/反序列化的方法來始終序列化/反序列化空。 從來沒有這樣做,但不應該太難做。 請參閱http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html

另一個解決方法是使用兩種登錄風格組合一個作用域會話bean,並標記不想用transient進行序列化的作用域會話bean。

+0

嗯。那麼,我想我想有loginData()而不是null的結果。即使它看起來像一個解決方法,你的方式也可能工作。說真的,我是唯一有這個問題的人嗎?不要傷心,我會等待另一個答案。 – 2013-05-09 19:55:42

+0

我猜想擁有不可序列化的會話範圍bean並不是一個好習慣。 如果你不得不,自定義序列化並不稀罕。順便說一句,我已經爲答案添加了一個新的工作空間。 – mamuso 2013-05-10 08:29:22

+0

你能指定第二個答案嗎?我想你可以使用'@Autowired(required = false)Serializable loginData; // MD5Salten'和'@Autowired transient LoginDataData; // Plaintext'在一起。 – 2013-05-10 08:44:36

0

您可以定義一個bean,其會話範圍由兩種風格組成,即可序列化和不可序列化的bean。

這可能是您的PermissionBean。

將Java關鍵字transient添加到LoginPlaintext屬性中。如果我沒有錯,這將被視爲你實現了我給你的第一個答案,即它不會序列化你的敏感數據,並且在反序列化時將返回null。

與前面的一個,我還沒有真正做到了,所以把它與鹽

0

一粒我說你爲什麼要儲存LoginPlaintext在會話開始?如果loginData()返回的值存儲在僅可序列化的Session中,沒有任何意義。如果要存儲會話,則存儲在Session中的任何內容都應該是可序列化的。因此,要麼不將Login存儲在會話中,要麼使Login爲瞬態,要麼不允許LoginPlaintext執行Login

+0

「LoginPlaintext」和「LoginMD5Salted」都不是** direclty **存儲在會話中,而是「PermissionBean」存儲在會話中。 Sessions中的'transient'字段與'PermissionBean'類似嗎?它們是會話對象的一部分,但不是可序列化的。 _存儲在Session中的任何東西都應該是serializable_ - 你的意思是Session-Object中的瞬態字段是不好的做法?嗯...... – 2013-05-15 09:00:10

+0

使會話可存儲的想法是,它可以在不同的服務器上恢復,或者在服務器重新啓動後恢復很長時間。在任何情況下,應用程序必須能夠繼續運行而不需要任何暫時的或不可序列化的對象。所以你可以,在這種情況下,你不需要序列化'Login',或者你不能,在這種情況下你不需要保存'LoginMD5Salted'。你的問題是你已經在會話中存儲了'Login',它只有_sometimes_ serializable。 – 2013-05-15 09:09:59

+0

是的,您可以使用'Login'瞬態來解決問題。 – 2013-05-15 17:46:13

相關問題