Почему Long.valueOf (stateMap.get ("time")) при использовании шифрования Base64, дающего java.lang.ClassCastException - PullRequest
0 голосов
/ 10 мая 2018

В целях понимания я комбинирую три различных кода java-файла в файле Test.java ниже. Строка long tokenTime = Long.valueOf(decodedMap.get("time")); дает исключение.

public class Test {

public static void main(String[] args) {

    Map<String, Long> stateMap = new HashMap<>();
    stateMap.put("userId",123L);
    stateMap.put("resId", 456L);
    stateMap.put("time", System.currentTimeMillis());

    String encodedString = jsonBase64Encode(stateMap);

    Map<String, Long> decodedMap = jsonBase64Decode(encodedString);
    long tokenTime = Long.valueOf(decodedMap.get("time"));
    System.out.println(tokenTime);

}


@SuppressWarnings("unchecked")
public static String jsonBase64Encode(Map<String, Long> stateMap){

    if(stateMap == null)
        return "";
    JSONObject jsonObject = new JSONObject();
    for( String key : stateMap.keySet() ){
        jsonObject.put(key, stateMap.get(key).toString());
    }
    byte[] jsonBytes = jsonObject.toString().getBytes();
    try {
        return Base64.getEncoder().encodeToString(jsonBytes);
    } catch (Exception e) {
        return "";
    }
}


public static Map<String, Long> jsonBase64Decode(String state)
{
    if(StringUtils.isBlank(state))
        return null;
    String decodedStr = null;
    try {
        byte[] decodedBytes = Base64.getDecoder().decode(state);
        decodedStr = new String(decodedBytes);
    } catch (Exception e) {
        return null;
    }
    if(StringUtils.isEmpty(decodedStr))
        return null;
    Map<String, Long> stateMap = new Gson().fromJson(decodedStr, 
            new TypeToken<HashMap<String, Object>>() {}.getType());
    return stateMap;
}

}

Я получаю ошибку ниже.

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at com.test.document.utils.Test.main(Test.java:26)

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Изменение

Map<String, Long> stateMap = new Gson().fromJson(decodedStr, new TypeToken<HashMap<String, Object>>() {}.getType());

до

Map<String, Long> stateMap = new Gson().fromJson(decodedStr, new TypeToken<HashMap<String, Long>>() {}.getType());

0 голосов
/ 10 мая 2018

Это означает, что ваша карта времени выполнения возвращает строку, когда ваш код был скомпилирован с ожиданием Long:

decodedMap.get("time") //At compile time, this is a Long

Но когда код выполняется во время выполнения, фактическим значением является строка.

Вы можете легко скопировать его, вставив строку в карту:

stateMap.put("resId", 456L);
((Map) stateMap).put("time", String.valueOf(System.currentTimeMillis()));

long tokenTime = Long.valueOf(stateMap.get("time"));

Последняя строка выше поднимает:

Исключение в потоке "main" java.lang.ClassCastException: java.lang.String не может быть приведено к java.lang.Long

Ваш JSON должен быть исправлен, или вам нужно изменить код для компиляции с Long.valueOf(String)

...