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

如何在Retrofit2的onResponse方法中用SharedPreferences存登录数据

解决Retrofit2解析JSON并存储到SharedPreferences的问题

嘿,我看了你的代码,发现几个关键问题导致你没法把响应数据存入SharedPreferences,而且跳转逻辑也有问题,咱们一步步来修复:

1. 修复数据模型类的JSON解析错误

首先看接口返回的JSON:

{ "User": [ { "SSN": "123456789", "FirstName": "Furkan", "User_Role": "1" } ] }

这里的User是一个数组(列表),但你的UserList类里定义的是单个User对象,这会导致Retrofit无法正确解析数据。另外你的User类里还有方法和变量不匹配的问题,比如userRole变量对应的方法是getUserRoleTypeId(),这会导致取值错误。

修改后的模型类应该是这样:

UserList类

public class UserList {
    @SerializedName("User")
    private List<User> userList; // 改成List<User>对应JSON数组

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
}

User类

public class User {
    @SerializedName("SSN")
    private String sSN;
    @SerializedName("FirstName")
    private String firstName;
    @SerializedName("User_Role")
    private int userRole; // 注意这里变量名和JSON字段对应,方法名也要匹配

    public String getSSN() {
        return sSN;
    }

    public void setSSN(String sSN) {
        this.sSN = sSN;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public int getUserRole() { // 方法名和变量名对应,之前的getUserRoleTypeId是错的
        return userRole;
    }

    public void setUserRole(int userRole) {
        this.userRole = userRole;
    }
}

2. 修复onResponse方法里的解析和存储逻辑

现在你的onResponse里有类型错误,而且没有正确取出数组里的User对象。修改后的代码如下:

@Override
public void onResponse(Call<UserList> call, Response<UserList> response) {
    progressDialog.dismiss();
    if(response.isSuccessful() && response.body() != null){
        // 从UserList里取出User列表,然后取第一个元素(因为你的返回里只有一个User)
        List<User> userList = response.body().getUserList();
        if(!userList.isEmpty()){
            User user = userList.get(0);
            
            // 存入SharedPreferences
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean(Constants.IS_LOGGED_IN, true);
            editor.putString(Constants.NAME, user.getFirstName());
            editor.putString(Constants.SSN, user.getSSN());
            editor.putInt(Constants.USERROLE, user.getUserRole());
            editor.apply(); // 或者commit(),apply是异步的,适合后台操作
            
            Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
            
            // 这里执行跳转逻辑,因为现在数据已经存入SharedPreferences了
            navigateToHome(user.getUserRole());
        } else {
            Toast.makeText(LoginActivity.this, "没有获取到用户信息", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(LoginActivity.this, "登录失败:" + response.message(), Toast.LENGTH_SHORT).show();
    }
}

3. 修复LoginActivity里的跳转逻辑错误

你之前在调用loginProcess()之后立刻去读取SharedPreferences,这时候Retrofit的异步请求还没完成,所以userRoleTypeId还是默认的0,导致跳转逻辑失效。应该把跳转逻辑单独写成一个方法,在onResponse里数据存储完成后调用:

添加跳转方法

private void navigateToHome(int userRole){
    Intent intent;
    if (userRole == 1) {
        intent = new Intent(this, OrganizerHomeActivity.class);
    } else if(userRole == 2 || userRole == 3) {
        intent = new Intent(this, UserHomeActivity.class);
    } else{
        Toast.makeText(LoginActivity.this, "错误的用户角色", Toast.LENGTH_SHORT).show();
        return;
    }
    startActivity(intent);
    finish(); // 关闭登录页面,避免返回
}

修改onClick里的login部分

把原来的跳转逻辑删掉,只保留调用loginProcess的代码:

case R.id.bLogin:
    String email = etEmail.getText().toString();
    String password = etPassword.getText().toString();
    if (!email.isEmpty() && !password.isEmpty()) {
        progressDialog.show();
        loginProcess(email, password);
        // 这里不要再读取SharedPreferences和跳转,交给onResponse处理
    } else {
        Toast.makeText(LoginActivity.this, "Fields are empty", Toast.LENGTH_SHORT).show();
    }
    break;

4. 其他小问题修复

  • 你的LoginActivity里重复设置了bLogin.setOnClickListener(this);,在onCreate里设置了两次,删掉其中一次就行。
  • 确保Constants类里的IS_LOGGED_IN、NAME、SSN、USERROLE都是正确的字符串常量,比如:
    public class Constants {
        public static final String IS_LOGGED_IN = "is_logged_in";
        public static final String NAME = "user_name";
        public static final String SSN = "user_ssn";
        public static final String USERROLE = "user_role";
    }
    

这样修改之后,你应该就能正确解析JSON响应,把数据存入SharedPreferences,并且根据用户角色跳转到对应的首页了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:52:12