中文亂碼就是編碼解碼的問題,編碼簡介-編碼方式
先說關鍵點:字節和字符間的編碼解碼,一定要表明編碼方式。
舉例開發中遇到的問題:
1.利用officeonline實現在線播放ppt, ppt文件名是中文, 將文件名用DEC加密後傳入接口,接口對其解密。
在ide中,解密後是正確的中文名稱,但打包運行或上環境,文件名稱就亂碼了。
在網上搜,有種在DES加密解密中 加入base64加密解密的解決辦法,確實可以防止中文亂碼問題,但因爲業務需求,文件名稱加密後的內容必須只含有數字和字母,不能有特殊符號,這種base64會有特殊符號,也不能使用。
最後發現,在DES解密時,是先得到字節數組,在用字符串構造方法得到字符串,這個步驟少了編碼方式。
正確方式:
可以看到,在字符串data 編碼爲字節時要指定編碼方式UTF-8,如果這少了,也會亂碼。在用字節數組構造字符串時,也需要指定編碼方式。
public static String decrypt(String data, String cryptKey) throws Exception {
return new String(decrypt(hex2byte(data.getBytes("UTF-8")),cryptKey.getBytes())
,"UTF-8");
}
//DES解密
private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// DES算法要求有一個可信任的隨機數源
SecureRandom sr = new SecureRandom();
// 從原始密匙數據創建一個DESKeySpec對象
DESKeySpec dks = new DESKeySpec(key);
// 創建一個密匙工廠,然後用它把DESKeySpec對象轉換成
// 一個SecretKey對象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher對象實際完成解密操作
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 用密匙初始化Cipher對象
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
// 現在,獲取數據並解密
// 正式執行解密操作
return cipher.doFinal(data);
}
錯誤方式:
public static String decrypt(String data, String cryptKey) throws Exception {
return new String(decrypt(hex2byte(data.getBytes("UTF-8")), cryptKey.getBytes()));
}
2.用JAVA URL類獲取阿里雲oss中文文件亂碼
在oss中上傳了一些中文名稱的文件,oss給出的path路徑 比如: http://domain/bucket/152/IOT物聯平臺123_幻燈片1.JPG,
在oss打開公有功能時,在瀏覽器上輸入url可以直接下載成功,但是用URL類訪問失敗。
這是因爲瀏覽器幫我們做了編碼:
登錄oss查看文件真正的path時,發現url是編碼後的,所以必須轉碼後再用URL類訪問才能成功。
URL url = new URL(fileName);
uc = (HttpURLConnection) url.openConnection();
is = uc.getInputStream();
if (uc.getResponseCode() != 200) {
logger.info("連接文件url失敗,返回狀態碼 -> {}, 響應信息 -> {}", uc.getResponseCode(), uc.getResponseMessage());
logger.info("連接文件url失敗,打開文件預覽異常,打開的文件地址爲{}", fileName);
info.setErrorMsg("打開文件預覽異常!");
}
對url進行編碼,空格也需要編碼,否則失敗。
public static String encodeUrl(String url) {
String path = url.substring(0,url.lastIndexOf("/")+1);
String query = url.substring(url.lastIndexOf("/")+1);
try {
String encodeQuery = URLEncoder.encode(query, "UTF-8");
return path + encodeQuery;
} catch (UnsupportedEncodingException e) {
return "Issue while encoding" + e.getMessage();
}
}