Java Android Gson从响应服务器将布尔值转换为int
帮帮我,伙计们! 请提供一个简单的解决方案,将Android中的类型boolean从服务器转换为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
{"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徽标=空;
}
注意上面的两个注释:
——此注释可以“重命名”字段,因此您甚至可以使用特殊字符(但不鼓励使用此注释,它通常用于将传入的JSON属性名称映射到javaCamelNamingConventions)@SerializedName
——此注释可以将特殊类型适配器“附加”到特定字段,以便将JSON属性转换为给定字段,反之亦然@JsonAdapter
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,因为响应映射类是泛型的,所以必须告诉GsonT
是什么。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”