"अपेक्षित BEGIN_OBJECT लेकिन पंक्ति 1 कॉलम 1 पर STRING था"


126

मेरे पास यह तरीका है:

public static Object parseStringToObject(String json) {
    String Object = json;
    Gson gson = new Gson();
    Object objects = gson.fromJson(object, Object.class);
    parseConfigFromObjectToString(object);
    return objects;
}

और मैं एक JSON के साथ पार्स करना चाहता हूं:

public static void addObject(String IP, Object addObject) {
    try {
        String json = sendPostRequest("http://" + IP + ":3000/config/add_Object", ConfigJSONParser.parseConfigFromObjectToString(addObject));
        addObject = ConfigJSONParser.parseStringToObject(json);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

लेकिन मुझे एक त्रुटि संदेश मिला:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: अपेक्षित BEGIN_OBJECT लेकिन पंक्ति 1 कॉलम 1 में STRING था


2
अपने पोस्ट रिक्वेस्ट द्वारा वापस लौटा JSON स्ट्रिंग पोस्ट करें।
एड्रियन लियोनहार्ड

अपने JSON स्ट्रिंग
bhspencer

जवाबों:


163

यहां तक ​​कि अपने JSON स्ट्रिंग को देखे बिना आप त्रुटि संदेश से बता सकते हैं कि यह आपकी कक्षा के उदाहरण में पार्स होने के लिए सही संरचना नहीं है।

GSON आपके JSON स्ट्रिंग को ऑब्जेक्ट ओपनिंग ब्रेस के साथ शुरू करने की उम्मीद कर रहा है। जैसे

{

लेकिन आपने जो स्ट्रिंग पास की है, वह एक खुले उद्धरण के साथ शुरू होती है

"

1
और विधि का बहुत नाम बताता है कि क्यों। parseStringToObjectयह बताता है कि यह एक JSON ऑब्जेक्ट की अपेक्षा करता है, जो हमेशा से शुरू होता है {
यशवित

12
'[' एक Json एरे की शुरुआत को इंगित करेगा न कि एक Json वस्तु को।
bhspencer

मुझे पता था कि .. लेकिन हमें उस पार्स के लिए क्या करना है ??
अजय मिस्त्री

@ अजय मिस्त्री यह स्पष्ट नहीं है कि आप और अधिक विस्तार के बिना क्या पूछ रहे हैं। मेरा सुझाव है कि JSON के जिस उदाहरण को आप पार्स करने का प्रयास कर रहे हैं, उसके साथ अपनी विशिष्ट समस्या को एक नए प्रश्न में पोस्ट करें।
bhspencer

1
प्रिय @bhspencer मैं एंड्रॉइड एपीके में रेट्रोफिट का उपयोग कर रहा हूं ताकि बैकएंड में {"ip":"192.167.1.15"}से एक साधारण जैसन प्राप्त कर सकें Restful EJB web service with jboss EAP 7.1। हालाँकि मुझे "अपेक्षित BEGIN_OBJECT मिलता है, लेकिन पंक्ति 1 कॉलम 1 में STRING था" कृपया मेरी सहायता करें ... यह मेरी वेब सेवा है: @Stateless @Path ("/ getflashcard") सार्वजनिक वर्ग GetFlashcard (@Interceptors (Validator.class) @GET @Produces (MediaType.APPLICATION_JSON) सार्वजनिक स्ट्रिंग getFlashcard () {स्ट्रिंग jsonString = नया JSONObject ()। डाल ("आईपी", "192.167.15")) toString (); वापसी jsonString; }}
होसिन अकाजानी

17

सर्वर से अमान्य JSON हमेशा एक अपेक्षित उपयोग का मामला होना चाहिए। ट्रांसमिशन के दौरान एक लाख चीजें गलत हो सकती हैं। Gson थोड़ा मुश्किल है, क्योंकि इसका एरर आउटपुट आपको एक समस्या देगा, और आपके द्वारा पकड़ा गया वास्तविक अपवाद एक अलग प्रकार का होगा।

उस सब को ध्यान में रखते हुए, ग्राहक पक्ष पर उचित समाधान है

try
{
  gson.fromJSON(ad, Ad.class);
  //...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
  //...

यदि आप यह जानना चाहते हैं कि सर्वर से प्राप्त JSON गलत क्यों है, तो आप अपवाद पर अपने कैच ब्लॉक के अंदर देख सकते हैं। लेकिन भले ही यह आपकी समस्या है, यह JSON को ठीक करने के लिए ग्राहक की जिम्मेदारी नहीं है जो इसे इंटरनेट से प्राप्त हो रहा है।

किसी भी तरह से, यह ग्राहक की जिम्मेदारी है कि वह यह तय करे कि जब यह खराब JSON हो तो क्या करें। दो संभावनाएं JSON को खारिज कर रही हैं और कुछ भी नहीं कर रही हैं, और फिर से कोशिश कर रही हैं।

यदि आप फिर से प्रयास करने जा रहे हैं, तो मैं अत्यधिक कोशिश / कैच ब्लॉक के अंदर एक झंडा स्थापित करने की सलाह देता हूं और फिर कोशिश / कैच ब्लॉक के बाहर उस ध्वज का जवाब देता हूं। नेस्टेड ट्राइ / कैच की संभावना है कि हमारे स्टाॅक ट्रेस और अपवादों के मेल नहीं खाने के कारण गेसन ने हमें इस झंझट में कैसे डाला।

दूसरे शब्दों में, भले ही मैं मानता हूँ कि यह बहुत सुंदर नहीं है, मैं सुझाऊंगा

boolean failed = false;

try
{
  gson.fromJSON(ad, Ad.class);
  //...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
  failed = true;
  //...
}

if (failed)
{
  //...

मैं जोड़ना चाहता हूं क्योंकि यह देखने के लिए मिल रहा है कि मैंने सादगी के लिए बूलियन का उपयोग किया था; "वास्तविक दुनिया" में, आप संभवतः एक स्ट्रिंग की उपस्थिति के लिए परीक्षण करना चाहेंगे, जहां आपने व्यक्तिगत डेटा / कैच ब्लॉक के अंदर एकत्र किए गए अपवाद डेटा को संग्रहीत किया है, अनिवार्य रूप से अपने आप को लेनदेन के इतिहास को फिर से खेलना ताकि आप समझदारी से निर्णय ले सकें जब आप अंततः असफल होने का निर्णय लेते हैं, तो पुन: प्रयास करें, और उपयोगी आउटपुट भेजें।
जेसिका पेनेल

5

Retrofit2 में, जब आप अपने मापदंडों को कच्चे में भेजना चाहते हैं तो आपको Scalars का उपयोग करना चाहिए।

पहले इसे अपनी श्रेणी में जोड़ें:

    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.squareup.retrofit2:converter-scalars:2.3.0'

    public interface ApiInterface {

    String URL_BASE = "http://10.157.102.22/rest/";

    @Headers("Content-Type: application/json")
    @POST("login")
    Call<User> getUser(@Body String body);

}

मेरा नमूना

   public class SampleActivity extends AppCompatActivity implements Callback<User> {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiInterface.URL_BASE)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        ApiInterface apiInterface = retrofit.create(ApiInterface.class);


        // prepare call in Retrofit 2.0
        try {
            JSONObject paramObject = new JSONObject();
            paramObject.put("email", "sample@gmail.com");
            paramObject.put("pass", "4384984938943");

            Call<User> userCall = apiInterface.getUser(paramObject.toString());
            userCall.enqueue(this);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void onResponse(Call<User> call, Response<User> response) {
    }

    @Override
    public void onFailure(Call<User> call, Throwable t) {
    }
}

संदर्भ: [ एक रेट्रोफिट अनुरोध के शरीर में कच्चे पूरे JSON को पोस्ट कैसे करें?


3

हो सकता है कि आपके JSON Objectठीक है, लेकिन प्रतिक्रिया है कि आप प्राप्त जब आप अवैध कनेक्ट अपने वैध data.Just नहीं है WiFi, तो आप एक अजीब प्रतिक्रिया मिली हो सकता है < html>.....< /html>कि GSONपार्स नहीं कर सकता।

try..catch..दुर्घटना से बचने के लिए आपको इस अजीब प्रतिक्रिया के लिए कुछ करने की आवश्यकता हो सकती है ।


3

मैं एक समाधान साझा करने आया हूं। नोटबुक को टांगने के लिए मजबूर करने के बाद मुझसे त्रुटि हुई। संभव समाधान clean preject


3

सुनिश्चित करें कि आपके पास वांछित वस्तुएं जैसे DATE / DATETIME आदि हैं। यदि आप सीधे JSON को बिना डिस्क्राइबलाइज़ किए भेज रहे हैं तो यह इस समस्या का कारण बन सकता है।


भेजने से पहले क्रमबद्ध?
ratzip

@ratzip क्षमा करें, मेरा मतलब था कि हमें DATE जैसी वस्तुओं के लिए एक deserializer (तर्क) जोड़ना चाहिए दिनांक और समय। मैं इस मुद्दे का सामना कर रहा था जब मैं एक JAVA ऑब्जेक्ट के लिए JsonObject का नक्शा बनाना चाहता था।
रवि वडजे

3

मेरी स्थिति में, मेरे पास एक "मॉडल" है, जिसमें एक के अपवाद के साथ कई स्ट्रिंग पैरामीटर शामिल हैं: यह बाइट सरणी है byte[]। कुछ कोड स्निपेट:

String response = args[0].toString();
Gson gson = new Gson();
BaseModel responseModel = gson.fromJson(response, BaseModel.class);

ऊपर अंतिम पंक्ति है जब

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column

शुरू हो रहा है। एसओ के माध्यम से खोज करते हुए, मुझे एहसास हुआ कि मुझे Adapterअपने BaseModelJsonObject को बदलने और बदलने के लिए कुछ रूप की आवश्यकता है। एक मॉडल में Stringऔर मिश्रित होने से byte[]बात जटिल हो जाती है। जाहिर है, Gsonवास्तव में स्थिति पसंद नहीं है।

मैं Adapterयह सुनिश्चित करने के लिए अंत करता हूं कि प्रारूप में byte[]परिवर्तित हो जाए Base64। यहाँ मेरी Adapterकक्षा है:

public class ByteArrayToBase64Adapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {

    @Override
    public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return Base64.decode(json.getAsString(), Base64.NO_WRAP);
    }

    @Override
    public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP));
    }
}

JSONObject को मॉडल में बदलने के लिए, मैंने निम्नलिखित का उपयोग किया:

Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64Adapter()).create();
BaseModel responseModel = customGson.fromJson(response, BaseModel.class);

इसी तरह, मॉडल को JSONObject में बदलने के लिए, मैंने निम्नलिखित का उपयोग किया:

Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64Adapter()).create();
String responseJSon = customGson.toJson(response);

कोड क्या कर रहा है, मूल रूप से class/objectइस (इस मामले में, byte[]वर्ग) को पुश करने के लिए होता है, Adapterजब भी इसे / fro JSONObject के रूपांतरण के दौरान सामना किया जाता है।



0

मेरे मामले में, मैं JSON ऑब्जेक्ट के रूप में लौट रहा हूं

{"डेटा": "", "संदेश": "उपस्थिति सफलतापूर्वक बच गई .. !!!", "स्थिति": "सफलता"}

इसे बदलकर हल किया गया

{"डेटा": {}, "संदेश": "उपस्थिति सफलतापूर्वक बच गई .. !!!", "स्थिति": "सफलता"}

यहाँ डेटा एक उप JsonObject है और यह {नहीं "" से शुरू होना चाहिए


0

यदि आपके json प्रारूप और चर ठीक हैं, तो अपने डेटाबेस प्रश्नों की जाँच करें ... भले ही डेटा db में सही ढंग से सहेजा गया हो, वास्तविक समस्या हो सकती है ... अपने प्रश्नों को पुनः जाँचें और पुनः प्रयास करें .. आशा है कि यह मदद करता है


0

Gson () का उपयोग करके पहले अपनी वस्तु को Json में बदलना न भूलें

  val fromUserJson = Gson().toJson(notificationRequest.fromUser)

फिर आप इस भयानक पुस्तकालय का उपयोग करके इसे आसानी से एक वस्तु में बदल सकते हैं

      val fromUser = Gson().fromJson(fromUserJson, User::class.java)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.