简体   繁体   中英

JSON Error "java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $"

public interface UserService {
    @POST(Constants.Api.URL_REGISTRATION)
    @FormUrlEncoded
    BaseWrapper registerUser(@Field("first_name") String firstname, @Field("last_name") String lastname, @Field("regNumber") String phone, @Field("regRole") int role);


 public BaseWrapper registerUser(User user) {
        return getUserService().registerUser(user.getFirstName(), user.getLastName(), user.getPhone(), user.getRole());
    }

This create Exception

 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $

Big thanks for help.

Let's look at the error you are receiving.

Expected BEGIN_OBJECT

Your JSON is an object, and all JSON objects are enclosed in curly braces ({}). BEGIN_OBJECT is therefore {. And it's expecting it somewhere.

but was STRING

But instead he found a string "Something". Still doesn't tell us where.

at line 1 column 1 path $

Ah, perfect. At line 1 column 1. Which is the start of the JSON. So you have forgotten to enclose the whole thing in {} (or at least you have forgotten the first one, but I bet you've forgotten them both).

清理和重建项目对我有用。

Recently i'd faced similiar issue and solutioned only by adding "Accept: application/json" into header section. So, if you're using retrofit 2.0;

1st solution: For post method add headers parameter like below;

@Headers({"Accept: application/json"})
@POST(Constants.Api.URL_REGISTRATION)
@FormUrlEncoded
BaseWrapper registerUser(@Field("first_name") String firstname, 
                         @Field("last_name") String lastname, 
                         @Field("regNumber") String phone, 
                         @Field("regRole") int role);

2nd solution: Add header into your interceptor class like this;

NB: Code is in kotlin

private fun getInterceptor(): Interceptor {
        try {
            return Interceptor {
                val request = it.request()
                it.proceed(
                    request.newBuilder()
                        .header("Accept", "application/json")
                        .header("Authorization", "$accessTokenType $accessToken")
                        .build()
                )
            }
        } catch (exception: Exception) {
            throw Exception(exception.message)
        }
    }
}

Hope it helps, happy coding :)

If you want to add the ArrayList in the json object and parse in GSON then make sure the ArrayList should be like below.

ArrayList<JSONObject>

Instead of

ArrayList<String>

and Parse like this.

ArrayList<JSONObject> mItem = new ArrayList<JSONObject>();
mItem.add(jsonObject);

// and Use like this.
JSONArray list = new JSONArray(mItem);
jsonObject.put("Item",list);

If your app was using stored data from previous version and you changed the data type, you may encounter this error.

For example: I had something stored as a String in my previous version. I later updated the class that had the data stored in it to an object type. When I ran it, I got this error. After clearing the app-data or re-installing it, the error cleared.

Clearing the app-data might be an easy fix.

SOLUTION

In Kotlin we can use Response of ResponseBody and manage the initial response within it.

viewModelScope.launch(Dispatchers.IO) {
        mainRepository.getAPIData(
            Constants.getRequestBody(requestBody.toString())
        ).let { it ->
            if (it.isSuccessful && it.code() == 200) {
                val responseBody = it.body()
                val res: String? = responseBody?.string()
                try {
                    val main = JSONObject(res!!)
                    Log.e("TAG", "onSuccess: " + main.toString())
                    if (main.getInt("StatusCode") == 200) {
                        val type = object : TypeToken<Response>() {}.type
                        val response: Response = Gson().fromJson(
                            main.toString(), type
                        )
                        Log.e("TAG", "onSuccess: " + response.toString())
                    } else {
                        apiResponseData.postValue(Resource.error(main.getString("Message"), null))
                        Log.e("TAG", "onFail: " + main.toString())
                    }
                } catch (exception: JSONException) {
                    Log.e("TAG", "Exception: " + exception.message)
                }
            }
        }
    }

Response - Retrofit

ResponseBody - okHttp

Response is actual model Response eg UserResponse

Here, getAPIData() is API call which returns Response of ResponseBody

apiResponseData is MutableLiveData

using this you can avoid JSON type cast error in response.

It's a proguard problem. In release minifyEnabled true broke the API models. You need to add Serializable in ResponseModel and in RequestModel API

https://i.stack.imgur.com/uHN22.png

清理并重建项目 这是由于 Gson 文件有些混乱造成的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM