小弟最近在研究spring oauth2
現在token已經使用了redis快取,然后發現還有個check_token介面,每次都會去取資料庫的客戶端資訊,為了方便管理客戶端資訊,這些資料肯定是需要放資料庫統一管理的,可是這種每次去取感覺不是很妥。
昨晚想了想,決定重寫JdbcClientDetailsService這個實作,為里面加上自己的快取業務,于是有了以下代碼(小弟c#轉java,獻丑了)。
/**
* 獲取快取
*
* @return 客戶端資訊
*/
private List<ClientDetails> getCache() {
List<ClientDetails> clientDetails = (List<ClientDetails>) redisUtil.get(JdbcClientDetailsConstant.JDBC_CLIENT_DETAILS_KEY);
return clientDetails;
}
/**
* 重新設定redis快取
*
* @return 客戶端資訊
*/
private List<ClientDetails> setCache() {
List<ClientDetails> clientDetails = super.listClientDetails();
redisUtil.set(JdbcClientDetailsConstant.JDBC_CLIENT_DETAILS_KEY, clientDetails);
return clientDetails;
}
我的想法是主要重寫loadClientByClientId這個獲取客戶端資訊的介面,沒快取就查詢資料庫中所有客戶端資訊,并且保存到redis快取,第二次有快取了就不用去查資料庫了,唯一要做的就是保證客戶端資訊增刪改要重新設定快取。
想法是美好的,等代碼啪啪啪敲完,第一次獲取token沒問題,然后試著進行第二次就報錯了
com.alibaba.fastjson.JSONException: autoType is not support. org.springframework.security.oauth2.provider.client.BaseClientDetails
于是點進ClientDetails,發現定義的是interface。。。
package org.springframework.security.oauth2.provider;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
/**
* Client details for OAuth 2
*
* @author Ryan Heaton
*/
public interface ClientDetails extends Serializable {
...
}
之前在研究flowable流程引擎的時候就發現有這種用法,關于用interface替代物體小弟實在是想不明白,百度也搜不到原因。。
現在卡死在這里了,想寫個物體繼承ClientDetails,可是那樣就要重寫他所有的方法了。。。
求大佬解惑
uj5u.com熱心網友回復:
從你的例外來看,是com.alibaba.fastjson.JSONException,我在想,為什么是這個例外呢?因為你貼出的代碼里面,看不見有關fastjson的資訊?讓我猜一下,你再讀取和存盤的時候,直接存盤的時候是一個物件,那我想是不是在你的方法內部用fastjson轉換成了字串存盤,然后取的時候再把它由字串轉換成物件了。
如果是這樣的話,先解釋一下為什么不行,由字串到物件,如果是一個POJO的話,他肯定可以轉,但是你給了一個介面,fastjson肯定不知道你想要的是哪個實作類,肯定不行。
那么這個問題怎么解決呢?
用fastjson肯定不行,你看人家都實作了Serializable,支持序列化的,所以你只要把物件序列化成物件流,然后轉換成位元組陣列,然后存盤在redis里面就行了,使用redis存盤位元組陣列的那個方法就行了,然后取出來是位元組資料,再轉換成物件流,再轉換成物件就行了。
這是redis存盤物件的常用方案。
關于Java的序列與反序列代碼,網上很多,搜一搜就行了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/134482.html
標籤:Java EE
上一篇:如何解決js引入后無法運行的問題(求大佬)~~~~急
下一篇:java零基礎適合看什么書
