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

Android SharedPreferences存JWT Token后调用API返回404问题排查

问题根源及解决方案

核心问题:请求执行顺序颠倒

从HttpLoggingInterceptor日志可知,获取信息的API请求比登录请求更早完成——这说明你在登录请求还未结束、Token还未正确写入SharedPreferences时,就发起了后续API调用。此时SharedPreferences中的Token要么是旧值,要么为空,导致请求头携带的Token不符合接口要求,最终触发404(多数是鉴权失败后被路由到错误路径,或直接因无效Token被拒绝)。

常见代码错误及修复

以Retrofit+OkHttp为例,错误写法通常是未正确处理异步请求的回调顺序:

  • 错误示例(请求并行执行):
// 发起登录请求
api.login(loginParams).enqueue(new Callback<LoginResponse>() {
    @Override
    public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
        if (response.isSuccessful()) {
            // 异步写入Token到SharedPreferences
            sharedPreferences.edit().putString("accessToken", response.body().getToken()).apply();
        }
    }
    @Override
    public void onFailure(Call<LoginResponse> call, Throwable t) {}
});
// 未等待登录完成,直接发起获取信息请求
api.getUserInfo().enqueue(new Callback<UserInfoResponse>() {
    @Override
    public void onResponse(Call<UserInfoResponse> call, Response<UserInfoResponse> response) {}
    @Override
    public void onFailure(Call<UserInfoResponse> call, Throwable t) {}
});
  • 修复方式(确保登录完成后再发起后续请求):
api.login(loginParams).enqueue(new Callback<LoginResponse>() {
    @Override
    public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
        if (response.isSuccessful()) {
            String validToken = response.body().getToken();
            // 写入Token(用commit同步写入,或apply后立即发起请求,内存中值已更新)
            sharedPreferences.edit().putString("accessToken", validToken).commit();
            // 登录成功、Token写入后,再调用获取信息API
            api.getUserInfo().enqueue(new Callback<UserInfoResponse>() {
                @Override
                public void onResponse(Call<UserInfoResponse> call, Response<UserInfoResponse> response) {
                    // 处理用户信息逻辑
                }
                @Override
                public void onFailure(Call<UserInfoResponse> call, Throwable t) {
                    // 处理请求失败
                }
            });
        }
    }
    @Override
    public void onFailure(Call<LoginResponse> call, Throwable t) {
        // 处理登录失败
    }
});

额外排查点

  • 检查Token拦截器逻辑:如果用拦截器自动添加Token到请求头,确保拦截器每次都从SharedPreferences读取最新值,而非初始化时的缓存值。
  • 验证接口有效性:用正确的Token通过Postman直接调用获取信息的API,确认接口路径本身是否正确,排除404是接口地址错误导致的可能。
  • 确认SharedPreferences写入:apply()是异步写入磁盘,但内存中的值会立即更新,只要在写入后读取,内存中是最新值;若跨进程操作,可改用commit()确保同步写入。

内容的提问来源于stack exchange,提问作者yu-k-m

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:00:18