Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何防止Gson将整数表示为浮点数_Java_Android_Gson - Fatal编程技术网

Java 如何防止Gson将整数表示为浮点数

Java 如何防止Gson将整数表示为浮点数,java,android,gson,Java,Android,Gson,当我尝试将字符串转换为json时,Gson有一些奇怪的行为。下面的代码将字符串草稿转换为json响应。有没有办法防止gson将“.0”添加到所有整数值 ArrayList<Hashtable<String, Object>> responses; Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType(); response

当我尝试将字符串转换为json时,Gson有一些奇怪的行为。下面的代码将字符串草稿转换为json响应。有没有办法防止gson将“.0”添加到所有整数值

ArrayList<Hashtable<String, Object>> responses;
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType();
responses = new Gson().fromJson(draft, ResponseList);

draft:
[ {"id":4077395,"field_id":242566,"body":""},
  {"id":4077398,"field_id":242569,"body":[[273019,0],[273020,1],[273021,0]]},
  {"id":4077399,"field_id":242570,"body":[[273022,0],[273023,1],[273024,0]]}
]

responses:
[ {id=4077395.0, body=, field_id=242566.0},
  {id=4077398.0, body=[[273019.0, 0.0], [273020.0, 1.0], [273021.0, 0.0]], field_id=242569.0},
  {id=4077399.0, body=[[273022.0, 0.0], [273023.0, 1.0], [273024.0, 0.0]], field_id=242570.0}
]
ArrayList响应;
类型ResponseList=newTypeToken(){}.getType();
responses=new Gson().fromJson(草稿,ResponseList);
草案:
[{“id”:4077395,“field_id”:242566,“body”:“”,
{“id”:4077398,“field_id”:242569,“body”:[[273019,0],[273020,1],[273021,0]},
{“id”:4077399,“field_id”:242570,“body”:[[273022,0],[273023,1],[273024,0]}
]
响应:
[{id=4077395.0,body=,field_id=242566.0},
{id=4077398.0,body=[[273019.0,0.0],[273020.0,1.0],[273021.0,0.0]],field_id=242569.0},
{id=4077399.0,body=[[273022.0,0.0],[273023.0,1.0],[273024.0,0.0]],field_id=242570.0}
]

您告诉Gson它正在寻找字符串到对象的映射列表,这本质上是说它要对对象的类型做出最佳猜测。因为对于数值字段,Gson必须默认为Float/Double

Gson的基本功能是检查要填充的对象的类型,以确定如何解析数据。如果你不给它任何暗示,它就不会很好地工作。一个选项是定义一个自定义JsonDeserializer,不过最好不要使用HashMap(当然也不要使用Hashtable!),而是向Gson提供更多关于它所期望的数据类型的信息

class Response {
  int id;
  int field_id;
  ArrayList<ArrayList<Integer>> body; // or whatever type is most apropriate
}

responses = new Gson()
            .fromJson(draft, new TypeToken<ArrayList<Response>>(){}.getType());
类响应{
int-id;
int字段的id;
ArrayList body;//或任何最合适的类型
}
响应=新的Gson()
.fromJson(草稿,新的TypeToken(){}.getType());

同样,Gson的全部要点是将结构化数据无缝地转换为结构化对象。如果你让它创建一个几乎未定义的结构,比如一个对象映射列表,那么你就破坏了Gson的全部功能,还不如使用一些更简单的JSON解析器。

我来晚了,但我自己也遇到了这个问题。在我的例子中,我不想在ArrayList中指定整数类型,因为它可以是字符串或整数

我的解决办法如下:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Double.class,  new JsonSerializer<Double>() {

    public JsonElement serialize(Double src, Type typeOfSrc,
                JsonSerializationContext context) {
            Integer value = (int)Math.round(src);
            return new JsonPrimitive(value);
        }
    });

Gson gs = gsonBuilder.create();
我不知道如何测试或转换这些数据类型,但这应该会让您走上正确的道路。

这是可行的:

 Gson gson = new GsonBuilder().
        registerTypeAdapter(Double.class,  new JsonSerializer<Double>() {   

    @Override
    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
        if(src == src.longValue())
            return new JsonPrimitive(src.longValue());          
        return new JsonPrimitive(src);
    }
 }).create();
Gson Gson=new GsonBuilder()。
registerTypeAdapter(Double.class,新的JsonSerializer(){
@凌驾
公共JsonElement序列化(双src,类型typeOfSrc,JsonSerializationContext){
如果(src==src.longValue())
返回新的JsonPrimitive(src.longValue());
返回新的JsonPrimitive(src);
}
}).create();

基本上,这个问题没有完美的答案。所有“解决方案”仅适用于某些情况。这是一个向gson团队报告的问题,不幸的是,他们似乎坚持“javascript没有整数类型”,好像他们没有意识到gson是用于java而不是javascript的。所以他们直到今天(2018年至今)才修复它,尽管像杰克逊这样的自由党根本没有这样的问题,尽管修复起来有多么容易。因此,您可能需要自己从gson源代码中修复这个问题,并构建自己的gson.jar。源文件是
gson/src/main/java/com/google/gson/internal/bind/ObjectTypeAdapter.java

case NUMBER:
   return in.nextDouble();
这是我的工作

步骤1: 将gson中的ObjectTypeAdapter复制到项目中,保持路径与gson中的路径相同 像这样

com
  - xxx
    - xxx
com
  - google
    - gson
      - internal
        - bind
          ObjectTypeAdapter
步骤2: 修改ObjectTypeAdapter

case NUMBER:
  return in.nextDouble();
修改为

case NUMBER:
  String number = in.nextString();
  try {
    return Long.valueOf(number);
  } catch (NumberFormatException e) {
    return Double.valueOf(number);
  }
嗯。 Gson将优先考虑项目中的ObjectTypeAdapter。

fun jsonToMap(json:JSONObject):Map{
    fun jsonToMap(json: JSONObject): Map<String, Any> {
        val doubles = Gson().fromJson<Map<String, Any>>(json.toString(), Map::class.java)
        fun doublesToLong(doubles: Map<String, Any>): Map<String, Any> = doubles
                .map { entry ->
                    Pair(entry.key, entry.value.let {
                        when (it) {
                            is Map<*, *> -> doublesToLong(it as Map<String, Any>)
                            is Double -> it.toLong()
                            else -> it
                        }
                    })
                }
                .toMap()
        return doublesToLong(doubles)
    }
val doubles=Gson().fromJson(json.toString(),Map::class.java) 趣味双打长(双打:地图):地图=双打 .map{entry-> 配对(entry.key、entry.value.let{ 什么时候{ is Map->doublesToLong(它作为Map) 是Double->it.toLong() 否则->它 } }) } .toMap() 返回双打(双打) }
类似的双精度到int的问题:@PatrickKafka,但这里的答案是gold。或者,试着转换成JacksonAlso(参见我为类似问题编写的文章);问题是,你必须将数据解析为一个
对象
,然后转换为你需要的任何对象。在我看来,听到“它可能是一个字符串或整数”是一个很大的危险信号。听起来你的JSON数据结构不好-你正在创建一个包含整数和字符串的列表?从技术上讲,JSON规范允许这样做,但它会给每个试图与之接口的反序列化程序带来麻烦。取而代之的是,考虑一个“保留整个列表字符串,如果只是一个巧合,有些是数字,B”将数字分割成自己的列表,或者c)将列表类型更改为更复杂的对象,以更好地反映数据的意图。@dimo414所有三种解决方案都有其缺陷:a)没有用,因为您不知道哪个是数字,哪个是字符串;b) 丢失排序信息(然后需要索引和开销的详细列表);c) 复杂对象将导致膨胀json@Enerccio复杂的数据需要复杂的表示,因此c)通常是可以接受的折衷方案。您的观点得到了很好的采纳,但在实践中,我会满足于混合数据类型通常会比它的价值更麻烦,并且通常重新检查您的需求会发现一种可供选择的结构,该结构可以满足您的需要,而无需跳过这些障碍。请随意发布一个带有具体用例的问题,我很乐意加入。您好,我找到了这个答案,并且使用了您在本文中提到的方式,但是,当它应该是int时,我得到了双精度:-(@armnotstrong这对哪个数字不起作用?上面的代码应该是
    fun jsonToMap(json: JSONObject): Map<String, Any> {
        val doubles = Gson().fromJson<Map<String, Any>>(json.toString(), Map::class.java)
        fun doublesToLong(doubles: Map<String, Any>): Map<String, Any> = doubles
                .map { entry ->
                    Pair(entry.key, entry.value.let {
                        when (it) {
                            is Map<*, *> -> doublesToLong(it as Map<String, Any>)
                            is Double -> it.toLong()
                            else -> it
                        }
                    })
                }
                .toMap()
        return doublesToLong(doubles)
    }