“Expected BEGIN_OBJECT but was STRING at line 1 column 1”

前端 未结 14 2207
误落风尘
误落风尘 2020-11-22 01:11

I have this method:

public static Object parseStringToObject(String json) {
    String Object = json;
    Gson gson = new Gson();
    Object objects = gson.f         


        
相关标签:
14条回答
  • 2020-11-22 01:54

    Don't forget to convert your object into Json first using Gson()

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

    Then you can easily convert it back into an object using this awesome library

          val fromUser = Gson().fromJson(fromUserJson, User::class.java)
    
    0 讨论(0)
  • 2020-11-22 01:56

    Invalid JSON from the server should always be an expected use case. A million things can go wrong during transmission. Gson is a bit tricky, because its error output will give you one problem, and the actual exception you catch will be of a different type.

    With all that in mind, the proper fix on the client side is

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

    If you want to know why the JSON you received from the server is wrong, you can look inside your catch block at the exception. But even if it is your problem, it's not the client's responsibility to fix JSON it is receiving from the internet.

    Either way, it is the client's responsibility to decide what to do when it gets bad JSON. Two possibilities are rejecting the JSON and doing nothing, and trying again.

    If you are going to try again, I highly recommend setting a flag inside the try / catch block and then responding to that flag outside the try / catch block. Nested try / catch is likely how Gson got us into this mess with our stack trace and exceptions not matching up.

    In other words, even though I'll admit it doesn't look very elegant, I would recommend

    boolean failed = false;
    
    try
    {
      gson.fromJSON(ad, Ad.class);
      //...
    }
    catch (IllegalStateException | JsonSyntaxException exception)
    {
      failed = true;
      //...
    }
    
    if (failed)
    {
      //...
    
    0 讨论(0)
  • 2020-11-22 01:57

    In Retrofit2, When you want to send your parameters in raw you must use Scalars.

    first add this in your 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);
    
    }
    

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

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

    0 讨论(0)
  • 2020-11-22 01:57

    I have come to share an solution. The error happened to me after forcing the notbook to hang up. possible solution clean preject.

    0 讨论(0)
  • 2020-11-22 01:57

    Make sure you have DESERIALIZED objects like DATE/DATETIME etc. If you are directly sending JSON without deserializing it then it can cause this problem.

    0 讨论(0)
  • 2020-11-22 01:58

    In my situation, I have a "model", consist of several String parameters, with the exception of one: it is byte array byte[]. Some code snippet:

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

    The last line above is when the

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

    is triggered. Searching through the SO, I realised I need to have some form of Adapter to convert my BaseModel to and fro a JsonObject. Having mixed of String and byte[] in a model does complicate thing. Apparently, Gson don't really like the situation.

    I end up making an Adapter to ensure byte[] is converted to Base64 format. Here is my Adapter class:

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

    To convert JSONObject to model, I used the following:

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

    Similarly, to convert the model to JSONObject, I used the following:

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

    What the code is doing is basically to push the intended class/object (in this case, byte[] class) through the Adapter whenever it is encountered during the convertion to/fro JSONObject.

    0 讨论(0)
提交回复
热议问题