1

I'm trying to send JSON via a POST request to a rest API with Retrofit. The problem I am having is that I cannot seem to figure out/use the type of data(JSONArray, String, INT ...etc) that retrofit wants in order for it to POST to my rest API. As of now, I have only tried to hard code the JSON in a string and parse it to Retrofit in hopes of it POSTing to the rest API and messing around with what type I input I use to give to retrofit to POST

when I try and parse a String I get the following: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ this error says that I am not parsing JSON. the problem is that I have no idea what to parse.

when I tried to parse either a JSONarray or a JSONobject or any other type of data my apps view would not load and my app would crash.

my code

interface SimpleApi {
    @POST("posttest.php")
    suspend fun postit(@Body post: String): Phone
}

this is the retrofit API that I. the String value is the one that I believe is giving me trouble, the Phone class is data class I am using for my recylerview.

    private fun TestGet() {
        val gson = GsonBuilder()
                .setLenient()
                .create()

        val api = Retrofit.Builder()
                    .baseUrl(BASE_URL)
                  .addConverterFactory(GsonConverterFactory.create(gson))
                    .build()
                    .create(SimpleApi::class.java)

            GlobalScope.launch(Dispatchers.IO) {
                val response = api.postit(test)//it wants a JSONarray
                //the above wants some kind of JSON to work I was passing Strings instead
                try {
                  //here lies the app logic and recylerview setup
                }catch (e: Exception){
                    println("you messed up the connection some how")
                }
            }
    }

this function is how I am calling my the rest API, parsing and returning the JSON and handling the business logic.

now the variable test has been a few things originally it was just a hardcoded string exactly like this private var test = "[\"text1\", \"text2\", \"text3\"]" and private var test = """["text1", "text2", "text3"]""" , this did not work, I have also tried to implement A GSON converter as stated above this did not work.

thank you for your time.

EDIT with out the addConverterFactory(GsonConverterFactory.create(gson)) I get the following errors FATAL EXCEPTION: DefaultDispatcher-worker-1 and com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $

m.seigmiller
  • 90
  • 11
  • Please add Okhttp debug interceptor and send the response of the api, it seems that the response from the service is not a valid json – Amin Feb 17 '21 at 01:38
  • @Amin how would I go about doing that? I tried to add it in and it would not compile, thanks for the tip though. – m.seigmiller Feb 17 '21 at 01:52

1 Answers1

1

The line .addConverterFactory(GsonConverterFactory.create(gson)), when applied means that retrofit is treating each payload that you pas as a Json Object. So, when you pass a simple string you get that error. A possible fix would be to convert your string array into a json array as explained here https://stackoverflow.com/a/10498107/404438.

Also check if the server response is a valid json, You could achieve this by adding logging interceptor.

Here is how you add the interceptor :

first, in your build.gradle:

    implementation "com.squareup.retrofit2:retrofit:2.6.0"
    implementation "com.squareup.retrofit2:converter-gson:2.6.0"
    implementation "com.squareup.okhttp3:logging-interceptor:3.11.0"

Then:

val gson = GsonBuilder()
                .setLenient()
                .create()

  val builder = OkHttpClient().newBuilder()
        builder.readTimeout(120, TimeUnit.SECONDS)
        builder.connectTimeout(30, TimeUnit.SECONDS)

        if (BuildConfig.DEBUG) {
            val interceptor = HttpLoggingInterceptor()
            interceptor.level = HttpLoggingInterceptor.Level.BASIC
            builder.addInterceptor(interceptor)
        }
  val client = builder.build()


  val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build()
bashizip
  • 562
  • 5
  • 14
  • With out `.addConverterFactory(GsonConverterFactory.create(gson))` I get the following error(s) `E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1` and `com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $` – m.seigmiller Feb 17 '21 at 01:49
  • @m.seigmiller see my edited answer on how to convert to json array – bashizip Feb 17 '21 at 01:52
  • 1
    ok so good-ish news, it failed. but I changed the `HttpLoggingInterceptor.Level.BASIC` to `HttpLoggingInterceptor.Level.BODY` and I got an error coming from my xammp server saying it was a problem with the PHP scripting! Thank you you have shown me how to proceed. – m.seigmiller Feb 17 '21 at 02:25