Java Android Gson从响应服务器将布尔值转换为int

Java Android Gson从响应服务器将布尔值转换为int,java,android,gson,Java,Android,Gson,帮帮我,伙计们! 请提供一个简单的解决方案,将Android中的类型boolean从服务器转换为int:) 当我登录时,我从服务器获得如下响应: {"status":{"error":0,"code":200,"message":"OK"},"response":{"profile":{"id":114,"username":"k@gmail.com","full_name":"k","phone":"9999999","verified":1,"admin":0,"allow_dev":fal

帮帮我,伙计们! 请提供一个简单的解决方案,将Android中的类型boolean从服务器转换为int:) 当我登录时,我从服务器获得如下响应:

{"status":{"error":0,"code":200,"message":"OK"},"response":{"profile":{"id":114,"username":"k@gmail.com","full_name":"k","phone":"9999999","verified":1,"admin":0,"allow_dev":false,"company":{"id":9,"name":"ООО \"Фингерз медиа\"","email":"info@fingers.by","sample":null,"logo":"http://storage.guardian-glass.fingersmedia.by/0cb56968b3cec1bba301db8d51d1015e.jpg"}},"access_token":"15629e234e04a54a5a44ef2aa4eccb1d"}}
然后我得到
未定义的异常:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期的数字,但为布尔值

这是因为JsonElement“allow_dev”是来自服务器的布尔值,而在Android中,我有类似int的“allow_dev

这是登录方法:

 private void login(String email, String pass) {
    showProgress();
    JsonObject params = new JsonObject();
    params.addProperty("username", email);
    params.addProperty("password", pass);
    UserOperationsTask task = new UserOperationsTask(UserOperationsTask.TaskMode.MODE_LOGIN, params) {
        @Override
        public void onLoadFinished(Bundle res) {
            hideProgress();
            String errorMessage = res.getString(UserOperationsTask.RESULT_ERROR_STRING);
            if (errorMessage != null) {
                showMessage(getString(R.string.login_error), getString(R.string.server_request_error));
            } else {
                String json = res.getString(UserOperationsTask.RESULT_JSON_STRING);
                if (json != null) {
                    JsonParser parser = new JsonParser();
                    JsonObject responseData = parser.parse(json).getAsJsonObject();
                    JsonObject companyObj = responseData.getAsJsonObject("profile").getAsJsonObject("company");
                   }
                setRegisteredMode();
            }
        }
    };
    task.execute(this);
}
这个方法解析响应,我尝试将allow_dev type从boolean转换为int,但我不知道我是否做得对

private Bundle parseProfileResponse(Context context, JsonObject responseData) {
    Log.d(TAG, "parseProfileResponse");

    // I tried convert allow_dev type from boolean to int
    String allow_dev_server = String.valueOf(responseData.get("allow_dev"));
    boolean b = allow_dev_server.equals("true");
    int allow_dev = b ? 1 : 0; // true == 1
    Profile profile;
    profile = GsonHolder.getGSONInstance().fromJson(responseData.getAsJsonObject("profile"), Profile.class);
    profile.allow_dev = allow_dev;

    Bundle res = new Bundle();
    res.putParcelable(RESULT_OBJ, profile);
    res.putString(RESULT_JSON_STRING, responseData.toString());
    try {
        Cache.saveToCache(context, profile);
    } catch (RemoteException e) {
        Log.d(TAG, "parseAuthResponse RemoteException: " + e.toString());
        res.putString(RESULT_ERROR_STRING, context.getString(R.string.database_error));
    } catch (OperationApplicationException e) {
        Log.d(TAG, "parseAuthResponse OperationApplicationException: " + e.toString());
        res.putString(RESULT_ERROR_STRING, context.getString(R.string.database_error));
    }
    return res;
}

我必须获得“允许”\u dev”将其转换为int并写入数据库。

如果您可以切换到映射,那么您可以使用静态类型所能提供的一切,而不是弱“类型化”
JsonElement
及其子类。它有几个优点:编译时检查、更健壮的代码、IDE支持等。主要缺点是您必须编写自定义映射,但是您可以使用一些工具(也可以在线)尝试基于给定的示例JSON生成简单的映射类(例如,这里非常流行的工具:)

现在,让我们创建一些映射。像下面这样的映射很少使用:
final
字段(用于不应以编程方式修改的“服务器响应”;Gson可以分配此类字段)<非原语的code>null和原语类型默认值的一些hack来欺骗编译器(比如
Integer.value(0)
但不仅仅是
0
:否则,
javac
可能会内联常量,因此Gson不会影响它们);没有getter/setter(数据传输对象只是数据包,但是是的,getter可以更好地工作)。无论如何,您可以使用您的样式,以下映射用于演示目的(映射代码甚至具有紧凑的格式:每行一个属性折叠注释)

最终课堂反应{
最终状态=空;
最终T反应=null;
}
最终班级状态{
最终整数错误=整数。值为(0);
最终整数代码=整数。值为(0);
最终字符串消息=null;
}
最终类配置文件和访问令牌{
最终配置文件=空;
@SerializedName(“访问令牌”)最终字符串accessToken=null;
}
最终课程简介{
最终int id=整数。valueOf(0);
最终字符串username=null;
@SerializedName(“全名”)最终字符串fullName=null;
最终字符串phone=null;
最终验证的整数=整数。值为(0);
final int admin=Integer.valueOf(0);
@SerializedName(“allow_dev”)@JsonAdapter(booleantotiontypeadapter.class)final int allowDev=Integer.valueOf(0);
最终公司=空;
}
末级公司{
最终int id=整数。valueOf(0);
最终字符串名称=null;
最终字符串email=null;
最终字符串样本=null;
最终URL徽标=空;
}
注意上面的两个注释:

  • @SerializedName
    ——此注释可以“重命名”字段,因此您甚至可以使用特殊字符(但不鼓励使用此注释,它通常用于将传入的JSON属性名称映射到javaCamelNamingConventions)
  • @JsonAdapter
    ——此注释可以将特殊类型适配器“附加”到特定字段,以便将JSON属性转换为给定字段,反之亦然
现在,让我们实现一个类型适配器,它可以将传入的
boolean
值转换为本地
int
值,反之亦然。请注意,类型适配器以流方式工作,所以您必须在读取期间动态读取JSON令牌流,当然,在写入期间生成JSON令牌流

final类booleantotiontypeadapter
扩展类型适配器{
//公共建设者可能是邪恶的,让他们尽可能少地暴露
//Gson仍然可以实例化此类型适配器本身
私有booleantTypeAdapter(){
}
@凌驾
@抑制警告(“资源”)
公共无效写入(最终JsonWriter out,最终整数值)
抛出IOException{
//如果给定的值为null,我们必须将`null`标记写入输出JSON标记流,以避免破坏JSON文档
如果(值==null){
out.nullValue();
返回;
}
//假设我们可以接受分别映射为false和true的0或1
开关(值){
案例0:
out.value(假);
打破
案例1:
out.value(true);
打破
违约:
//或者尽快抛出异常
抛出新的IllegalArgumentException(“无法将“+值+”转换为布尔文字”);
}
}
@凌驾
公共整数读取(中的最终JsonReader)
抛出IOException{
//查看下一个令牌类型,如果为null,则也返回null值
if(in.peek()==NULL){
返回null;
}
//否则,将下一个标记解析为布尔值,并将其映射到1或0
在.nextBoolean()中返回?1:0;
}
}
这就是你在格森所需要的。现在,对于整个JSON,因为响应映射类是泛型的,所以必须告诉Gson
T
是什么。Gson在
fromJson
方法中接受
java.lang.reflect.Type
,并且该类型可以同时保存原始类型和参数化类型,因此Gson可以更准确地(反)序列化

private静态最终类型概要文件和AccessTokenResponse=new-TypeToken(){
}.getType();
最终响应=gson.fromJson(JSON、profileAndAccessTokenResponse);
System.out.println(response.response.profile.allowDev);
System.out.println(gson.toJson(response、profileAndAccessTokenResponse));
输出:

0
{“状态”:{“e”