"BEGIN_OBJECT bekleniyordu, ancak 1. satır, 1. sütunda STRING idi"


126

Bu yönteme sahibim:

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

Ve bir JSON'u şununla ayrıştırmak istiyorum:

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

Ama bir hata mesajı alıyorum:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: BEGIN_OBJECT bekleniyordu ancak 1. satır sütun 1'de STRING idi


2
Gönderi isteğiniz tarafından döndürülen JSON dizesini gönderin.
Adrian Leonhard

JSON dizenizi
gönderin

Yanıtlar:


163

JSON dizenizi görmeden bile, hata mesajından, sınıfınızın bir örneğine ayrıştırılacak doğru yapının olmadığını anlayabilirsiniz.

Gson, JSON dizenizin bir nesne açma küme ayracı ile başlamasını bekliyor. Örneğin

{

Ama ona ilettiğiniz dize, açık bir alıntı ile başlar

"

1
Yöntemin adı da nedenini gösteriyor. parseStringToObjecther zaman ile başlayan bir JSON nesnesi beklediğini önerir {.
yshavit

12
'[', bir Json nesnesi değil, bir Json Dizisinin başlangıcını gösterir.
bhspencer

bunu biliyordum .. ama bunu ayrıştırmak için ne yapmalıyız ??
Ajay Mistry

@AjayMistry Daha fazla ayrıntı olmadan ne sorduğunuz net değil. Ayrıştırmaya çalıştığınız JSON örneğiyle özel sorununuzu yeni bir soruya göndermenizi öneririm.
bhspencer

1
Ben robot apk'de güçlendirme kullanıyorum Sevgili @bhspencer gibi basit bir json almak için {"ip":"192.167.1.15"}gelen Restful EJB web service with jboss EAP 7.1arka uç. Ancak "Bekleniyor BEGIN_OBJECT ancak 1. satırda STRING oldu" Lütfen bana yardım edin ... Bu benim web hizmetim: @Stateless @Path ("/ getflashcard") genel sınıf GetFlashcard {@Interceptors (Validator.class) @GET @Produces (MediaType.APPLICATION_JSON) public String getFlashcard () {String jsonString = new JSONObject (). Put ("ip", "192.167.1.15"). ToString (); dönüş jsonString; }}
Hosein Aqajani

17

Sunucudan gelen geçersiz JSON, her zaman beklenen bir kullanım örneği olmalıdır. İletim sırasında milyonlarca şey ters gidebilir. Gson biraz zor, çünkü hata çıktısı size bir sorun verecek ve yakaladığınız asıl istisna farklı bir türde olacak.

Tüm bunları akılda tutarak, müşteri tarafında doğru düzeltme,

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

Sunucudan aldığınız JSON'un neden yanlış olduğunu öğrenmek istiyorsanız, istisnada catch bloğunuzun içine bakabilirsiniz. Ancak bu sizin sorununuz olsa bile, internetten aldığı JSON'u düzeltmek müşterinin sorumluluğunda değildir.

Her iki durumda da, kötü JSON aldığında ne yapılacağına karar vermek müşterinin sorumluluğundadır. İki olasılık JSON'u reddedip hiçbir şey yapmamak ve tekrar denemektir.

Tekrar deneyecekseniz, try / catch bloğunun içine bir bayrak koymanızı ve ardından bu bayrağa try / catch bloğunun dışında yanıt vermenizi şiddetle tavsiye ederim. İç içe geçmiş dene / yakala, büyük olasılıkla Gson'un yığın izleme ve uyuşmayan istisnalarla bizi bu karmaşaya nasıl soktuğudur.

Başka bir deyişle, çok şık görünmediğini kabul etsem de tavsiye ederim

boolean failed = false;

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

if (failed)
{
  //...

Eklemek istiyorum, çünkü bu, basitlik için bir boole kullandığım görünümleri alıyor; "gerçek dünyada" büyük olasılıkla, bireysel deneme / yakalama blokları içinde topladığınız istisna verilerini depoladığınız bir dizenin varlığını test etmek isteyeceksiniz, esasen işlemin geçmişini kendinize yeniden oynatarak yeniden denemek ve sonunda başarısız olmaya karar verdiğinizde yararlı çıktılar göndermek.
Jessica Pennell

5

Retrofit2'de, parametrelerinizi ham olarak göndermek istediğinizde Skaler kullanmalısınız.

önce bunu gradle'ınıza ekleyin:

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

}

SampleActivity:

   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) {
    }
}

Referans: [ Bir İyileştirme talebinin gövdesindeki ham JSON'un tamamı nasıl YAYINLANIR?


3

Belki senin JSON Objecthaklı, ama aldığı cevap geçersiz bağladığınızda gibi geçerli data.Just değil WiFi, bir garip tepki aldı olabilir ayrıştıramıyor.< html>.....< /html>GSON

try..catch..çökmeyi önlemek için bu garip yanıt için bazılarını yapmanız gerekebilir .


3

Bir çözüm paylaşmaya geldim. Not defteri kapatmaya zorladıktan sonra hata bana oldu. olası çözüm clean preject.


3

DATE / DATETIME vb. Gibi nesnelerin DESERIALIZED olduğundan emin olun. JSON'u seriyi kaldırmadan doğrudan gönderiyorsanız, bu soruna neden olabilir.


Göndermeden önce SERİLEŞTİRİLDİ mi?
ratzip

@ratzip Üzgünüm, DATE gibi nesneler için bir seri çözümleyici (mantık) eklememiz gerektiğini kastetmiştim. DATETIME. Bir JsonObject'i bir JAVA nesnesine eşlemek istediğimde bu sorunla karşı karşıyaydım.
Ravi Wadje

3

Benim durumumda, birkaç String parametresinden oluşan bir "model" var, bunlardan biri hariç: bayt dizisi byte[]. Bazı kod parçacığı:

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

Yukarıdaki son satır,

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

tetiklendi. SO'da arama yaparken, kendimi bir JsonObject'e ve JsonObject'e Adapterdönüştürmek için bir şekilde ihtiyacım olduğunu fark ettim BaseModel. Bir modelin içinde Stringve byte[]içinde karışık olması işleri karmaşıklaştırır. Görünüşe göre, Gsondurumu pek sevmiyorsun.

AdapterFormata byte[]dönüştürülmesini sağlamak için bir hazırladım Base64. İşte Adaptersınıfım:

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'i modele dönüştürmek için aşağıdakileri kullandım:

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

Benzer şekilde, modeli JSONObject'e dönüştürmek için aşağıdakileri kullandım:

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

Kodun yaptığı şey, temelde JSONObject'e / fro dönüştürme sırasında karşılaşıldığında amaçlanan class/object(bu durumda, byte[]sınıfı) Adapteritmektir.



0

Benim durumumda, JSON Nesnesini şu şekilde döndürüyorum:

{"data": "", "message": "Katılım Başarıyla Kaydedildi .. !!!", "status": "başarılı"}

Olarak değiştirilerek çözüldü

{"data": {}, "message": "Katılım Başarıyla Kaydedildi .. !!!", "status": "başarılı"}

Burada veriler bir JsonObject alt nesnesidir ve {not "" ile başlamalıdır.


0

json formatınız ve değişkenleriniz uygunsa, veritabanı sorgularınızı kontrol edin ... veriler db'ye doğru kaydedilmiş olsa bile asıl sorun orada olabilir ... sorgularınızı tekrar kontrol edin ve tekrar deneyin .. Umarım yardımcı olur


0

Önce Gson () kullanarak nesnenizi Json'a dönüştürmeyi unutmayın.

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

Sonra bu harika kitaplığı kullanarak onu kolayca bir nesneye dönüştürebilirsiniz.

      val fromUser = Gson().fromJson(fromUserJson, User::class.java)

0

El yazısıyla yazılmış bir json dosyasından okuduğum bir durum vardı. JSON mükemmeldir. Ancak bu hata oluştu. Yani bir java nesnesinden json dosyasına yazıyorum, sonra o json dosyasından okuyorum. işler iyi. El yazısı json ile java nesnesinden gelen json arasında herhangi bir fark göremedim. Ötesinde denendiCompare hiçbir fark görmüyor. Sonunda iki dosya boyutunun biraz farklı olduğunu fark ettim ve winHex aracını kullandım ve fazladan şeyler tespit ettim. Bu yüzden benim durumumun çözümü, iyi json dosyasının bir kopyasını alın, içeriği içine yapıştırın ve kullanın.

görüntü açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.