Вопрос-ответ

"Expected BEGIN_OBJECT but was STRING at line 1 column 1"

"Ожидаемый BEGIN_OBJECT, но был строкой в строке 1, столбец 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;
}

И я хочу разобрать 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


Переведено автоматически
Ответ 1

Даже не видя вашу строку JSON, вы можете сказать из сообщения об ошибке, что это неправильная структура для разбора в экземпляре вашего класса.

Gson ожидает, что ваша строка JSON будет начинаться с открывающей объект фигурной скобки. например

{

Но строка, которую вы ему передали, начинается с открытых кавычек

"
Ответ 2

Недопустимый JSON с сервера всегда должен быть ожидаемым вариантом использования. Миллион вещей может пойти не так во время передачи. Gson немного сложен, потому что его вывод ошибки выдаст вам одну проблему, а фактическое исключение, которое вы поймаете, будет другого типа.

Имея все это в виду, правильное исправление на стороне клиента - это

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

Если вы хотите знать, почему JSON, полученный вами с сервера, неверен, вы можете заглянуть в свой блок catch и посмотреть исключение. Но даже если это ваша проблема, клиент не несет ответственности за исправление JSON, который он получает из Интернета.

В любом случае, клиент несет ответственность за то, чтобы решить, что делать, когда он получает неверный JSON. Две возможности - отклонить JSON и ничего не делать, а затем попробовать снова.

Если вы собираетесь попробовать еще раз, я настоятельно рекомендую установить флаг внутри блока try / catch, а затем отвечать на этот флаг вне блока try / catch. Вложенная попытка / catch, вероятно, из-за того, что Gson втянул нас в эту неразбериху с нашей трассировкой стека и не совпадающими исключениями.

Другими словами, хотя я признаю, что это выглядит не очень элегантно, я бы рекомендовал

boolean failed = false;

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

if (failed)
{
//...
Ответ 3

Недавно у меня была похожая проблема, и я нашел интересное решение. По сути, мне нужно было десериализовать следующую вложенную строку JSON в мой POJO:

"{\"restaurant\":{\"id\":\"abc-012\",\"name\":\"good restaurant\",\"foodType\":\"American\",\"phoneNumber\":\"123-456-7890\",\"currency\":\"USD\",\"website\":\"website.com\",\"location\":{\"address\":{\"street\":\" Good Street\",\"city\":\"Good City\",\"state\":\"CA\",\"country\":\"USA\",\"postalCode\":\"12345\"},\"coordinates\":{\"latitude\":\"00.7904692\",\"longitude\":\"-000.4047208\"}},\"restaurantUser\":{\"firstName\":\"test\",\"lastName\":\"test\",\"email\":\"test@test.com\",\"title\":\"server\",\"phone\":\"0000000000\"}}}"

В итоге я использовал regex для удаления открытых кавычек из начала и конца JSON, а затем использовал метод apache.commons unescapeJava(), чтобы отменить его. В основном передал нечистый JSON в следующий метод, чтобы получить обратно очищенный:

private String removeQuotesAndUnescape(String uncleanJson) {
String noQuotes = uncleanJson.replaceAll("^\"|\"$", "");

return StringEscapeUtils.unescapeJava(noQuotes);
}

затем использовал Google GSON, чтобы преобразовать его в мой собственный объект:

MyObject myObject = new.Gson().fromJson(this.removeQuotesAndUnescape(uncleanJson));
Ответ 4

В Retrofit2, когда вы хотите отправить свои параметры в raw, вы должны использовать скаляры.

сначала добавьте это в свой 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);

}

мой 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) {
}
}

Ссылка: [Как ОПУБЛИКОВАТЬ необработанный JSON целиком в теле запроса на доработку?

java json