前言
公司存在多個項目需要使用 kk 的預覽服務,但是使用的版本并不一緻。部分項目因為上線時間較早,是以使用的是舊版的 kk,比如 2.x。kk 本身也在疊代,是以造成了舊項目在接入新版 kk 服務的時候産生了不相容的現象。
問題原因
部分項目使用的 2.x 版本 kk 是使用的未 base64 編碼的 url,而新版 4.0.0 的則是需要傳入編碼過的 url 才可以支援預覽。新版的 kk 在很早前因為需要徹底解決各種奇葩檔案名預覽問題,是以 url 采用了 base64+urlencode 雙編碼。
舊項目當中在接入預覽服務時需要傳入明文位址,這樣就導緻預覽服務無法使用了。
解決方案
可選的處理辦法有兩種。
額外傳參
一個是增加一個參數告訴預覽服務是使用的明文位址,預覽服務需要根據額外的參數做相容處理,初始版本是使用的這種辦法,保證服務可用。
這種方法的缺點就是預覽服務和使用方需要同時修改代碼,但是使用方的修改量較小。
不額外傳參
利用 url 本身的内容是否是經過 base64 編碼的來區分處理。
好處就是不需要接入方做任何額外的改動,使用者感覺不到變化。
修改方法
修改的關鍵就是判斷字元串是否是經過 base64 加密的:将字元串解密後再将解密字元串加密回去與原來的值做比較,如果相同就是 base64。網上存在較多文章但是并不适用,是以這裡結合 kk 的實際情況需要修改判斷方法。
- 修改工具類檔案
,在後面追加判斷 url 是否 base64 編碼的方法。server/src/main/java/cn/keking/utils/WebUtils.java
/**
* url是否base64編碼
*
* @param str str
* @return boolean
*/
public static boolean isBase64(String str) {
// 将字元串解密後再将解密字元串加密回去與原來的值做比較 如果相同就是base64
try {
String decodeStr = new String(Base64Utils.decodeFromString(str), StandardCharsets.UTF_8);
return str.equals(Base64Utils.encodeToString(decodeStr.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
return false;
}
}
- 修改過濾器
,追加對 url 參數的判斷。server/src/main/java/cn/keking/web/filter/TrustHostFilter.java
在
doFilter
方法中處理:
if (WebUtils.isBase64(url)) {
url = new String(Base64Utils.decodeFromString(url), StandardCharsets.UTF_8);
}
- 修改主程式
,在server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java
方法中追加判斷。onlinePreview
if (WebUtils.isBase64(url)){
fileUrl = new String(Base64.decodeBase64(url), StandardCharsets.UTF_8);
} else {
fileUrl = url;
}
然後重新編譯項目就可以使用了。
總結
本次修改是為了向下相容非 base64 編碼的檔案位址,是以是服務降級,有可能出現奇葩檔案名預覽問題。因為需要統一服務的原因是以才會産生這個臨時修改方案,總體還是建議在合适時間适配到新版的 kk 服務,保證使用者體驗。