You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Base64编解码时,Long.valueOf(stateMap.get("time"))为何抛出ClassCastException

解决ClassCastException: String无法转换为Long的问题

问题根源

咱们先拆解下代码里的核心矛盾:

  1. 在jsonBase64Encode方法中,你把Map里的Long值转成了String存入JSONObject:

    jsonObject.put(key, stateMap.get(key).toString());
    

    这就导致最终生成的JSON里,所有原本的Long数值都变成了字符串格式——比如"time":"1699999999999",而不是预期的数字类型"time":1699999999999。

  2. 到了解码环节,你用Gson把JSON字符串解析成HashMap<String, Object>,却直接返回Map<String, Long>。这时候Map里的"time"值实际是String类型,当你执行Long.valueOf(decodedMap.get("time"))时,相当于把String对象强行传给需要Long参数的方法,自然触发了ClassCastException。

解决方案

这里有两种靠谱的修复方式,你可以根据实际场景选择:

方案1:统一编码解码的类型逻辑(推荐)

直接修改编码逻辑,保留Long的数值类型存入JSONObject,这样解码时Gson能自动解析成Long,彻底避免类型不匹配问题:

@SuppressWarnings("unchecked")
public static String jsonBase64Encode(Map<String, Long> stateMap){
    if(stateMap == null) return "";
    JSONObject jsonObject = new JSONObject();
    for( String key : stateMap.keySet() ){
        // 去掉toString(),直接存入Long类型值
        jsonObject.put(key, stateMap.get(key));
    }
    byte[] jsonBytes = jsonObject.toString().getBytes();
    try {
        return Base64.getEncoder().encodeToString(jsonBytes);
    } catch (Exception e) {
        return "";
    }
}

同时把解码方法的TypeToken泛型改成HashMap<String, Long>,让Gson直接解析出Long类型的Map:

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;
    // 修改泛型为<String, Long>,匹配原始Map的类型
    Map<String, Long> stateMap = new Gson().fromJson(decodedStr, 
        new TypeToken<HashMap<String, Long>>() {}.getType());
    return stateMap;
}

之后主方法里直接取值即可,不需要额外转换:

long tokenTime = decodedMap.get("time");

方案2:如果必须保留编码时转String的逻辑

如果因为特殊需求不能修改编码逻辑,那就在取值时手动把String转成Long:

// 替换原有的报错行
long tokenTime = Long.parseLong(decodedMap.get("time").toString());

不过这种方式需要确保"time"对应的字符串一定是合法的数字,否则会抛出NumberFormatException,不如方案1稳妥。

额外小建议

尽量保持编码和解码的类型一致,减少不必要的类型转换,既能降低出错概率,也能让代码更易维护。如果需要更严谨,还可以在解码方法中加入类型校验,提前处理不符合预期的情况。

内容的提问来源于stack exchange,提问作者surendrapanday

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:53:08