31

json 文字列を Java オブジェクトに変換し、長い形式で表示する必要があります。json 文字列は、長い数値の固定配列です。

{numbers
[ 268627104, 485677888, 506884800 ] }

変換するコードは、0 で終わる数値を除いて、すべての場合に正常に機能します。これらの数値を指数表記の数値形式に変換します。

   public static Object fromJson(HttpResponse response, Class<?> classOf)
    throws IOException {
    InputStream instream = response.getResponseInputStream();                   

    Object obj = null;
    try {
        Reader reader = new InputStreamReader(instream, HTTP.UTF_8);

        Gson gson = new Gson();

        obj = gson.fromJson(reader, classOf); 

        Logger.d(TAG, "json --> "+gson.toJson(obj));
    } catch (UnsupportedEncodingException e) {
        Logger.e(TAG, "unsupported encoding", e);
    } catch (Exception e) {
        Logger.e(TAG, "json parsing error", e);
    }

    return obj;
}

実際の結果: Java オブジェクト: 268627104、485677888、5.068848E+8

最後の数値が科学表記法形式に変換されていることに注意してください。それを回避したり、防止したり、元に戻したりするために何ができるかを誰かが提案できますか? 私はGson v1.7.1を使用しています

4

8 に答える 8

10

もう 1 つの回避策は、代わりに JsonParser クラスを使用することです。これにより、ユーザー定義のクラスではなく Gson オブジェクト表現 (JsonElement) が返されますが、科学表記法への変換の問題は回避されます。

import java.lang.reflect.Type;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;

public class GsonTest
{
    public static void main(String[] args)
    {
        String json = "{numbers:[268627104,485677888,506884800]}";

        Gson gson = new Gson();
        Type type = new TypeToken<Map<String, Object>>(){}.getType();
        Map<String, Object> jsonMap = gson.fromJson(json, type);
        System.out.println("Gson output:");
        System.out.println(jsonMap);

        JsonParser jsonParser = new JsonParser();
        JsonElement jsonElement = jsonParser.parse(json);
        System.out.println("JsonParser output:");
        System.out.println(jsonElement);
    }
}

コード出力:

Gson output:  
{numbers=[2.68627104E8, 4.85677888E8, 5.068848E8]}  
JsonParser output:  
{"numbers":[268627104,485677888,506884800]}
于 2013-01-16T23:10:43.943 に答える
5

同じ問題が発生しました。いくつかの調査の後、ここに私が見つけたものがあります。

動作:

  • Gson
    小数部分のない数値の場合、次のGsonように変換しますDouble
  • ジャクソン
    小数部分のない数値の場合、またはJacksonとして変換しますが、数値の大きさによって異なります。IntegerLong

可能な解決策:

  • Gsonの戻り値を からDoubleLong明示的に変換します。
  • Jackson代わりに使用してください。
    私はこれが好きです。

コード - テストJackson

ParseNumberTest.java:

import java.util.List;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * test - jackson parse numbers,
 * 
 * @author eric
 * @date Jan 13, 2018 12:28:36 AM
 */
public class ParseNumberTest {
    @Test
    public void test() throws Exception {
    String jsonFn = "numbers.json";

    ObjectMapper mapper = new ObjectMapper();

    DummyData dd = mapper.readValue(this.getClass().getResourceAsStream(jsonFn), DummyData.class);
    for (Object data : dd.dataList) {
        System.out.printf("data type: %s, value: %s\n", data.getClass().getName(), data.toString());
        Assert.assertTrue(data.getClass() == Double.class || data.getClass() == Long.class || data.getClass() == Integer.class);

        System.out.printf("%s\n\n", "------------");
    }
    }

    static class DummyData {
    List<Object> dataList;

    public List<Object> getDataList() {
        return dataList;
    }

    public void setDataList(List<Object> dataList) {
        this.dataList = dataList;
    }
    }
}

数字.json:

{
    "dataList": [
        150000000000,
        150778742934,
        150000,
        150000.0
    ]
}

実行方法:

  • Jacksonテスト ケースは&に基づいていTestNGます。
  • numbers.jsonと同じパッケージに入れますParseNumberTest.java
  • testng テストとして実行すると、解析結果の型と値が出力されます。

出力:

data type: java.lang.Long, value: 150000000000
------------

data type: java.lang.Long, value: 150778742934
------------

data type: java.lang.Integer, value: 150000
------------

data type: java.lang.Double, value: 150000.0
------------

PASSED: test
于 2018-01-12T17:12:10.643 に答える
-1

0 で終わる gson 形式の数値を科学表記法に変換するという問題の解決策が見つかりませんでした。代わりに、回避策を使用して、この科学的表記法をコンマでフォーマットした double に変換しました。「値」はjson文字列です。

  private String formatNumber(String value) { 
    double dValue = Double.parseDouble(value);
    String pattern = "#,###";
    DecimalFormat formatter = new DecimalFormat(pattern);
    String newNumber = formatter.format(dValue);

            return newNumber;
}

これは質問に対する回答ではありませんが、問題を回避してシステムの要求に応じて数値を表示するための追加の手順です。

于 2012-07-24T01:49:14.137 に答える