java - फ्लोट के रूप में पूर्णांकों को व्यक्त करने से Gson को कैसे रोकें




android (5)

जब मैं स्ट्रिंग को जोंस में बदलने की कोशिश करता हूं, तो Gson का कुछ अजीब व्यवहार होता है। नीचे दिया गया कोड स्ट्रिंग ड्राफ्ट को json प्रतिक्रियाओं में बदल देता है। क्या गेस को '.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}
]

Answers

यह काम:

 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();

मूल रूप से, इस मुद्दे का कोई सही जवाब नहीं है। सभी "समाधान" केवल कुछ मामलों के लिए काम करते हैं। यह एक मुद्दा है जो गन्स टीम को सूचित किया जाता है, दुर्भाग्य से उन्हें लगता है कि "जावास्क्रिप्ट के पास कोई पूर्णांक प्रकार नहीं है" जैसे कि उन्हें पता ही नहीं है कि यह संदेश जावा के लिए है जावास्क्रिप्ट नहीं। इसलिए उन्होंने इसे आज (2018 अब) तक ठीक करने से इनकार कर दिया, क्योंकि जैकसन जैसे अन्य लोगों के पास ऐसा कोई मुद्दा नहीं है, बावजूद इसके इसे ठीक करना कितना आसान है। इसलिए आपको gson स्रोत कोड से समस्या को स्वयं ठीक करना होगा और अपना स्वयं का gson.jar बनाना होगा। स्रोत फ़ाइल gson/src/main/java/com/google/gson/internal/bind/ObjectTypeAdapter.java

case NUMBER:
   return in.nextDouble();

आप गन्सन को बता रहे हैं कि यह स्ट्रिंग्स के ऑब्जेक्ट्स के नक्शे की एक सूची की तलाश कर रहा है, जो अनिवार्य रूप से ऑब्जेक्ट के प्रकार के रूप में सबसे अच्छा अनुमान लगाने के लिए कहता है। चूंकि JSON पूर्णांक और फ़्लोटिंग पॉइंट फ़ील्ड के बीच अंतर नहीं करता है, इसलिए Gson को फ़्लोट / डबल को संख्यात्मक फ़ील्ड के लिए डिफ़ॉल्ट करना पड़ता है।

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());

फिर, 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 gs = new Gson(); साथ डिफ़ॉल्ट Gson परिभाषा का उपयोग करने के बजाय Gson gs = new Gson(); , मैंने एक पूर्णांक वापस करने के लिए Double.class क्रमांकन को ओवरराइड किया है।

मेरे मामले में, मेरे JSON के भीतर स्ट्रिंग्स और इंटेगर हैं, लेकिन मेरे पास कोई युगल नहीं है, इसलिए यह समस्या पैदा नहीं करता है।

यदि आपको एक डबल या फ्लोट मूल्य की आवश्यकता है, तो मुझे लगता है कि कुछ तर्क जोड़ना संभव होगा जो प्रत्येक डेटाटाइप के लिए विशिष्ट विशेषताओं के मूल्य का परीक्षण करता है और एक उचित मूल्य लौटाता है। कुछ इस तरह

if(/*source has a decimal point*/){
  return new JsonPrimitive(src); 
} else if (/* source has some attribute of a Float */){
  Float value = /*convert the src value from double to a Float */;
  return new JsonPrimitive(value);
} else {
  //it looks like an integer
  Integer value = (int)Math.round(src);
  return new JsonPrimitive(value);
}

मुझे नहीं पता कि मेरे सिर के ऊपर से उन डेटाटिप्स को कैसे जांचना या परिवर्तित करना है, लेकिन यह आपको सही रास्ते पर लाना चाहिए।


मुझे लगता है कि आपकी समस्या यह कॉन्फ़िगरेशन निर्णय है -XX:PermSize=320m -XX:MaxPermSize=320m आपके पेमस्पेस को गतिशील रूप से बदलने की इजाजत नहीं देता है, आप इसे समाप्त करते समय डेडलॉक कर रहे हैं - याद रखें कि इंटर्न कैश पर्मस्पेस का उपयोग करता है। मैं बदलना -XX:MaxPermSize=320m से -XX:MaxPermSize=512m







java android gson