2015-02-09 18 views
32

mam tej metody:"Oczekiwany BEGIN_OBJECT ale STRING w wierszu 1 kolumny 1"

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

I chcę analizować JSON z:

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

Ale pojawia się komunikat o błędzie:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Oczekiwany BEGIN_OBJECT ale STRING w wierszu 1, kolumnie 1

+4

uważnie patrzeć na komunikat o błędzie; Jak myślisz, co ci to mówi? – fge

+2

Wyślij ciąg JSON zwrócony przez żądanie postu. –

+0

Poślij ciąg JSON – bhspencer

Odpowiedz

73

Nawet jeśli nie widzisz swojego ciągu JSON, z komunikatu o błędzie można stwierdzić, że nie jest to poprawna struktura, która zostanie przetworzona w instancję klasy.

Gson oczekuje, że twój ciąg JSON zacznie od klamry otwierającej obiekt. na przykład

{ 

Ale ciąg zdałeś do niej rozpoczyna się otwartymi cytaty

" 
+0

I sama nazwa metody sugeruje, dlaczego. 'parseStringToObject' sugeruje, że oczekuje obiektu JSON, który zawsze zaczyna się od' {'. – yshavit

+0

Zaczyna się od '{' lub '[' – devnull69

+4

'[' wskazuje początek obiektu Json Array, a nie Json. – bhspencer

3

Może twoja JSON Object ma rację, ale odpowiedź, że nie otrzymał to ważne data.Just jak po podłączeniu nieprawidłowa WiFi, możesz otrzymać dziwną odpowiedź, której nie można przeanalizować.

może zaistnieć potrzeba wykonania pewnej dziwnej odpowiedzi, aby uniknąć awarii.

6

Nieprawidłowy JSON z serwera powinien zawsze być oczekiwanym przypadkiem użycia. Milion rzeczy może pójść źle podczas transmisji. Gson jest nieco trudny, ponieważ jego wyjście błędów da ci jeden problem, a rzeczywisty wyjątek, który złapiesz, będzie innego rodzaju.

Przy tym wszystkim pamiętać, prawidłowe ustalenie po stronie klienta jest

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

Jeśli chcesz wiedzieć dlaczego JSON otrzymaniu od serwera jest źle, można spojrzeć wewnątrz bloku catch u wyjątek. Ale nawet jeśli to jest twój problem, to nie klient jest odpowiedzialny za naprawienie JSON, które otrzymuje z Internetu.

Tak czy inaczej, klient jest odpowiedzialny za podjęcie decyzji, co zrobić, gdy stanie się zły JSON. Dwie możliwości odrzucają JSON i nie robią nic, i próbują ponownie.

Jeśli zamierzasz spróbować ponownie, bardzo polecam ustawienie flagi wewnątrz bloku try/catch, a następnie odpowiedź na tę flagę poza blokiem try/catch. Zagnieżdżone try/catch jest prawdopodobnie tym, jak Gson wprowadził nas w ten bałagan z naszym śledzeniem stosu i wyjątkami nie pasującymi do siebie.

Innymi słowy, chociaż muszę przyznać, że nie wygląda bardzo elegancki, polecam

boolean failed = false; 

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

if (failed) 
{ 
    //... 
+0

Uratowałeś mi życie. – viper

1

W Retrofit2, gdy chcesz wysłać swoje parametry surowca należy użyć skalarów.

najpierw dodać ten w Gradle:

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", "[email protected]"); 
     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) { 
} 

}

referencyjny: [How to POST raw whole JSON in the body of a Retrofit request?