title: How to fix java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ with correct JSON form
body: <p>I have this code in my Activity : </p>
  
  <pre><code>package com.salammedindonesia.ptsalammeddeviceindonesia.activities;
  
  import android.Manifest;
  import android.app.ProgressDialog;
  import android.content.ActivityNotFoundException;
  import android.content.DialogInterface;
  import android.content.Intent;
  import android.content.pm.PackageManager;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Bundle;
  import android.support.annotation.NonNull;
  import android.support.v4.app.ActivityCompat;
  import android.support.v4.content.ContextCompat;
  import android.support.v7.app.AlertDialog;
  import android.support.v7.app.AppCompatActivity;
  import android.support.v7.widget.LinearLayoutManager;
  import android.support.v7.widget.RecyclerView;
  import android.util.Log;
  import android.view.View;
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.ImageView;
  import android.widget.Spinner;
  import android.widget.TextView;
  import android.widget.Toast;
  
  import com.salammedindonesia.ptsalammeddeviceindonesia.R;
  import com.salammedindonesia.ptsalammeddeviceindonesia.adapters.ImageBarangRecyclerAdapter;
  import com.salammedindonesia.ptsalammeddeviceindonesia.models.AddResponse;
  import com.salammedindonesia.ptsalammeddeviceindonesia.networks.ApiService;
  import com.salammedindonesia.ptsalammeddeviceindonesia.networks.InternetConnection;
  import com.salammedindonesia.ptsalammeddeviceindonesia.networks.RetrofitConfig;
  import com.salammedindonesia.ptsalammeddeviceindonesia.utils.FileUtils;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Objects;
  
  import butterknife.BindView;
  import butterknife.ButterKnife;
  import butterknife.OnClick;
  import okhttp3.MediaType;
  import okhttp3.MultipartBody;
  import okhttp3.RequestBody;
  import retrofit2.Call;
  import retrofit2.Callback;
  import retrofit2.Response;
  
  public class PermohonanPenawaranActivity extends AppCompatActivity {
  
      @BindView(R.id.company_profile_text_view)
      TextView companyProfileTextView;
      @BindView(R.id.text_spinner_customer)
      TextView textSpinnerCustomer;
      @BindView(R.id.spinner_customer)
      Spinner spinnerCustomer;
  
      @BindView(R.id.edit_text_keterangan)
      EditText editTextKeterangan;
      @BindView(R.id.edit_text_nama_pemesan)
      EditText editTextNamaPemesan;
      @BindView(R.id.edit_text_jabatan_pemesan)
      EditText editTextJabatanPemesan;
      @BindView(R.id.edit_text_pemesan_phone)
      EditText editTextPemesanPhone;
      @BindView(R.id.edit_text_pemesan_email)
      EditText editTextPemesanEmail;
  
      @BindView(R.id.image_view_npwp)
      ImageView imageViewNpwp;
      @BindView(R.id.text_view_nama_file_npwp)
      TextView textViewNamaFileNpwp;
  
      @BindView(R.id.button_select_image)
      Button buttonSelectImage;
      @BindView(R.id.recycler_image_upload)
      RecyclerView recyclerImageUpload;
      @BindView(R.id.button_submit_permohonan)
      Button buttonSubmitPermohonan;
  
      private static final String TAG = PermohonanPenawaranActivity.class.getSimpleName();
      private static final int REQUEST_CODE = 6384;
      private static final int REQUEST_CODE_ASK_PERMISSIONS = 124;
  
      private ProgressDialog mProgressBar;
      private List&lt;Uri&gt; uriList;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_permohonan_penawaran);
          ButterKnife.bind(this);
          mProgressBar = new ProgressDialog(PermohonanPenawaranActivity.this);
          uriList = new ArrayList&lt;&gt;();
          getCustomerData();
      }
  
      @OnClick({R.id.company_profile_text_view, R.id.text_spinner_customer, R.id.button_select_image, R.id.button_submit_permohonan})
      public void onViewClicked(View view) {
          switch (view.getId()) {
              case R.id.company_profile_text_view:
                  break;
              case R.id.text_spinner_customer:
                  break;
              case R.id.button_select_image:
                  if (askForPermission())
                      showChooser();
                  break;
              case R.id.button_submit_permohonan:
                  addNewRequestPesananBarang();
                  break;
          }
      }
  
      private void getCustomerData() {
  
      }
  
      private void addNewRequestPesananBarang() {
          ApiService apiService = RetrofitConfig.getInitRetrofit();
          Call&lt;AddResponse&gt; addResponseCall = apiService.addPesananBarang(
                  1,
                  editTextNamaPemesan.getText().toString(),
                  editTextJabatanPemesan.getText().toString(),
                  editTextPemesanPhone.getText().toString(),
                  editTextPemesanEmail.getText().toString()
          );
          addResponseCall.enqueue(new Callback&lt;AddResponse&gt;() {
              @Override
              public void onResponse(@NonNull Call&lt;AddResponse&gt; call, @NonNull Response&lt;AddResponse&gt; response) {
                  if (!Objects.requireNonNull(response.body()).isResponse()) {
                      Toast.makeText(PermohonanPenawaranActivity.this, R.string.string_some_thing_wrong, Toast.LENGTH_SHORT).show();
                  } else {
                      uploadImagesToServer();
                  }
              }
  
              @Override
              public void onFailure(@NonNull Call&lt;AddResponse&gt; call, @NonNull Throwable t) {
                  Toast.makeText(PermohonanPenawaranActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
              }
          });
      }
  
      private void uploadImagesToServer() {
          if (InternetConnection.checkConnection(PermohonanPenawaranActivity.this)) {
              ApiService apiService = RetrofitConfig.getInitRetrofit();
              showProgress();
  
              // create list of file parts (photo, video, ...)
              List&lt;MultipartBody.Part&gt; parts = new ArrayList&lt;&gt;();
  
              if (uriList != null) {
                  // create part for file (photo, video, ...)
                  for (int i = 0; i &lt; uriList.size(); i++) {
                      parts.add(prepareFilePart(uriList.get(i)));
                  }
              }
  
              // finally, execute the request
              Call&lt;AddResponse&gt; call = apiService.uploadImageBarang(parts);
  
              call.enqueue(new Callback&lt;AddResponse&gt;() {
                  @Override
                  public void onResponse(@NonNull Call&lt;AddResponse&gt; call, @NonNull Response&lt;AddResponse&gt; response) {
                      Log.d("JSON : ", String.valueOf(response.body()));
                      hideProgress();
                      if (response.isSuccessful()) {
                          if (!Objects.requireNonNull(response.body()).isResponse()) {
                              Toast.makeText(PermohonanPenawaranActivity.this, R.string.string_some_thing_wrong, Toast.LENGTH_SHORT).show();
                          } else {
                              Toast.makeText(PermohonanPenawaranActivity.this, "All data and images successfully uploaded!", Toast.LENGTH_SHORT).show();
                          }
                      }
  
                  }
  
                  @Override
                  public void onFailure(@NonNull Call&lt;AddResponse&gt; call, @NonNull Throwable t) {
                      hideProgress();
                      Toast.makeText(PermohonanPenawaranActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
                      Log.d("Error : ", t.getMessage());
                  }
              });
  
          } else {
              hideProgress();
              Toast.makeText(PermohonanPenawaranActivity.this, R.string.string_internet_connection_not_available, Toast.LENGTH_SHORT).show();
          }
      }
  
      private void showChooser() {
          // Use the GET_CONTENT intent from the utility class
          Intent target = FileUtils.createGetContentIntent();
          // Create the chooser Intent
          Intent intent = Intent.createChooser(
                  target, getString(R.string.chooser_title));
          try {
              startActivityForResult(intent, REQUEST_CODE);
          } catch (ActivityNotFoundException e) {
              // The reason for the existence of aFileChooser
          }
      }
  
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if (requestCode == REQUEST_CODE) {// If the file selection was successful
              if (resultCode == RESULT_OK) {
                  if (data.getClipData() != null) {
                      int count = data.getClipData().getItemCount();
                      int currentItem = 0;
                      while (currentItem &lt; count) {
                          Uri imageUri = data.getClipData().getItemAt(currentItem).getUri();
                          //do something with the image (save it to some directory or whatever you need to do with it here)
                          currentItem = currentItem + 1;
                          Log.d("Uri Selected", imageUri.toString());
                          try {
                              // Get the file path from the URI
                              String path = FileUtils.getPath(this, imageUri);
                              Log.d("Multiple File Selected", path);
  
                              uriList.add(imageUri);
                              recyclerImageUpload.setLayoutManager(new LinearLayoutManager(PermohonanPenawaranActivity.this));
                              recyclerImageUpload.setAdapter(new ImageBarangRecyclerAdapter(PermohonanPenawaranActivity.this, uriList));
  
                          } catch (Exception e) {
                              Log.e(TAG, "File select error", e);
                          }
                      }
                  } else if (data.getData() != null) {
                      //do something with the image (save it to some directory or whatever you need to do with it here)
                      final Uri uri = data.getData();
                      Log.i(TAG, "Uri = " + uri.toString());
                      try {
                          // Get the file path from the URI
                          final String path = FileUtils.getPath(this, uri);
                          Log.d("Single File Selected", path);
  
                          uriList.add(uri);
                          recyclerImageUpload.setLayoutManager(new LinearLayoutManager(PermohonanPenawaranActivity.this));
                          recyclerImageUpload.setAdapter(new ImageBarangRecyclerAdapter(PermohonanPenawaranActivity.this, uriList));
  
                      } catch (Exception e) {
                          Log.e(TAG, "File select error", e);
                      }
                  }
              }
          }
          super.onActivityResult(requestCode, resultCode, data);
      }
  
      private void showProgress() {
          mProgressBar.show();
          mProgressBar.setMessage("Loading......");
          buttonSelectImage.setEnabled(false);
      }
  
      private void hideProgress() {
          mProgressBar.dismiss();
          buttonSelectImage.setEnabled(true);
      }
  
      @NonNull
      private MultipartBody.Part prepareFilePart(Uri fileUri) {
          // https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
          // use the FileUtils to get the actual file by uri
          File file = FileUtils.getFile(this, fileUri);
  
          // create RequestBody instance from file
          RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-file"), file);
  
          // MultipartBody.Part is used to send also the actual file name
          return MultipartBody.Part.createFormData("upload_image_barang", file.getName(), requestFile);
      }
  
      private boolean askForPermission() {
          int currentAPIVersion = Build.VERSION.SDK_INT;
          if (currentAPIVersion &gt;= Build.VERSION_CODES.M) {
              int hasCallPermission = ContextCompat.checkSelfPermission(PermohonanPenawaranActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);
              if (hasCallPermission != PackageManager.PERMISSION_GRANTED) {
                  // Ask for permission
                  // need to request permission
                  if (ActivityCompat.shouldShowRequestPermissionRationale(PermohonanPenawaranActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                      // explain
                      showMessageOKCancel(
                              new DialogInterface.OnClickListener() {
                                  @Override
                                  public void onClick(DialogInterface dialogInterface, int i) {
                                      ActivityCompat.requestPermissions(PermohonanPenawaranActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSIONS);
                                  }
                              });
                      // if denied then working here
                  } else {
                      // Request for permission
                      ActivityCompat.requestPermissions(PermohonanPenawaranActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSIONS);
                  }
  
                  return false;
              } else {
                  // permission granted and calling function working
                  return true;
              }
          } else {
              return true;
          }
      }
  
      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          if (requestCode == REQUEST_CODE_ASK_PERMISSIONS) {
              if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  // Permission Granted
                  showChooser();
              } else {
                  // Permission Denied
                  Toast.makeText(PermohonanPenawaranActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
              }
          } else {
              super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          }
      }
  
      private void showMessageOKCancel(DialogInterface.OnClickListener okListener) {
  
          AlertDialog.Builder builder = new AlertDialog.Builder(PermohonanPenawaranActivity.this);
          final AlertDialog dialog = builder.setMessage("You need to grant access to Read External Storage")
                  .setPositiveButton("OK", okListener)
                  .setNegativeButton("Cancel", null)
                  .create();
  
          dialog.setOnShowListener(new DialogInterface.OnShowListener() {
              @Override
              public void onShow(DialogInterface arg0) {
                  dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(
                          ContextCompat.getColor(PermohonanPenawaranActivity.this, android.R.color.holo_blue_light));
                  dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(
                          ContextCompat.getColor(PermohonanPenawaranActivity.this, android.R.color.holo_red_light));
              }
          });
  
          dialog.show();
  
      }
  }
  </code></pre>
  
  <p>Then I've set my Retrofit here : </p>
  
  <pre><code>package com.salammedindonesia.ptsalammeddeviceindonesia.networks;
  
  import com.google.gson.Gson;
  import com.google.gson.GsonBuilder;
  
  import java.util.concurrent.TimeUnit;
  
  import okhttp3.OkHttpClient;
  import retrofit2.Retrofit;
  import retrofit2.converter.gson.GsonConverterFactory;
  
  public class RetrofitConfig {
  
      private static Retrofit setInitRetrofit() {
          OkHttpClient client = new OkHttpClient.Builder()
                  .readTimeout(30, TimeUnit.SECONDS)
                  .connectTimeout(30, TimeUnit.SECONDS)
                  .build();
          Gson gson = new GsonBuilder()
                  .setLenient()
                  .create();
          return new Retrofit.Builder()
                  .baseUrl("http://192.168.43.103/PermohonanPenawaranHarga/Permohonan/")
                  .addConverterFactory(GsonConverterFactory.create(gson))
                  .client(client)
                  .build();
      }
  
      public static ApiService getInitRetrofit() {
          return setInitRetrofit().create(ApiService.class);
      }
  
  }
  </code></pre>
  
  <p>And I have this code in my ApiService interface : </p>
  
  <pre><code>package com.salammedindonesia.ptsalammeddeviceindonesia.networks;
  
  import com.salammedindonesia.ptsalammeddeviceindonesia.models.AddImageBarangResponse;
  import com.salammedindonesia.ptsalammeddeviceindonesia.models.AddResponse;
  
  import java.util.List;
  
  import okhttp3.MultipartBody;
  import okhttp3.RequestBody;
  import okhttp3.ResponseBody;
  import retrofit2.Call;
  import retrofit2.http.Field;
  import retrofit2.http.FormUrlEncoded;
  import retrofit2.http.GET;
  import retrofit2.http.Headers;
  import retrofit2.http.Multipart;
  import retrofit2.http.POST;
  import retrofit2.http.Part;
  
  
  public interface ApiService {
      @Headers({"Content-Type: application/json", "Content-Type: multipart/form-data"})
      @Multipart
      @POST("addImageBarang")
      Call&lt;AddResponse&gt; uploadImageBarang(
              @Part List&lt;MultipartBody.Part&gt; upload_image_barang
      );
  
      @FormUrlEncoded
      @POST("addNewRequestPesananBarang")
      Call&lt;AddResponse&gt; addPesananBarang(
              @Field("customer_id") int customer_id,
              @Field("pemesan_name") String pemesan_name,
              @Field("pemesan_jabatan") String pemesan_jabatan,
              @Field("pemesan_phone") String pemesan_phone,
              @Field("pemesan_email") String pemesan_email
      );
  }
  </code></pre>
  
  <p>And this is My POJO : </p>
  
  <pre><code>package com.salammedindonesia.ptsalammeddeviceindonesia.models;
  
  import lombok.Data;
  
  @Data
  public class AddResponse {
      private boolean response;
  }
  </code></pre>
  
  <p>Then Last, this is My API code that created with CodeIgniter framework :</p>
  
  <p>This is My Controller : </p>
  
  <pre><code>&lt;?php 
  /**
   * 
   */
  
  class Permohonan extends CI_Controller
  {
  
      function __construct() {
          parent::__construct();
          $this-&gt;load-&gt;model('Permohonan_model');
          $this-&gt;load-&gt;helper(array('form', 'url'));
      }
  
      public function getCustomerData() {
          $data['customerData'] = $this-&gt;Permohonan_model-&gt;getCustomerData();
          echo json_encode($data);    
      }
  
      public function addImageBarang() {
  
          // $permohonan_id = $this-&gt;input-&gt;post('permohonan_id');
  
          if(!empty($_FILES['upload_image_barang']['name'])) {
  
              $filesCount = count($_FILES['upload_image_barang']['name']);
  
              for($i = 0; $i &lt; $filesCount; $i++) { 
  
                  $_FILES['upload_File']['name'] = $_FILES['upload_image_barang']['name'][$i]; 
                  $_FILES['upload_File']['type'] = $_FILES['upload_image_barang']['type'][$i]; 
                  $_FILES['upload_File']['tmp_name'] = $_FILES['upload_image_barang']['tmp_name'][$i]; 
                  $_FILES['upload_File']['error'] = $_FILES['upload_image_barang']['error'][$i]; 
                  $_FILES['upload_File']['size'] = $_FILES['upload_image_barang']['size'][$i]; 
  
                  $uploadPath = './uploadImages/BarangPesanan/'; 
  
                  $config['upload_path'] = $uploadPath; 
                  $config['allowed_types'] = 'gif|jpg|png'; 
  
                  $this-&gt;load-&gt;library('upload', $config);
                  $this-&gt;upload-&gt;initialize($config);
  
                  if($this-&gt;upload-&gt;do_upload('upload_File')) {
  
                      $fileData = $this-&gt;upload-&gt;data();
  
                      // $uploadData[$i]['permohonan_id'] = implode(",", $permohonan_id);
                      $uploadData[$i]['image_name'] = $fileData['file_name'];
  
                  }
              } 
  
              if(!empty($uploadData)) {
                  //Insert file information into the database
                  $insertImageBarang = $this-&gt;Permohonan_model-&gt;insertImageBarang($uploadData);
  
                  if ($insertImageBarang === TRUE) {
                      $data['response'] = true;
                      echo json_encode($data);
                  } else {
                      $data['response'] = false;
                      echo json_encode($data);
                  }
              }
          }
      }
  
      public function addNewRequestPesananBarang() {
  
          $customer_id = $this-&gt;input-&gt;post('customer_id');
          $pemesan_name = $this-&gt;input-&gt;post('pemesan_name');
          $pemesan_jabatan = $this-&gt;input-&gt;post('pemesan_jabatan');
          $pemesan_phone = $this-&gt;input-&gt;post('pemesan_phone');
          $pemesan_email = $this-&gt;input-&gt;post('pemesan_email');
  
          $pesananValue = array(
              'customer_id' =&gt; $customer_id, 
              'pemesan_name' =&gt; $pemesan_name, 
              'pemesan_jabatan' =&gt; $pemesan_jabatan, 
              'pemesan_phone' =&gt; $pemesan_phone, 
              'pemesan_email' =&gt; $pemesan_email 
          );
  
          $addNewRequestPesananBarang = $this-&gt;Permohonan_model-&gt;insertNewRequestPesananBarang($pesananValue);
  
          if ($addNewRequestPesananBarang === TRUE) {
              $data['response'] = true;
              echo json_encode($data);
          } else {
              $data['response'] = false;
              echo json_encode($data);
          }
  
      }
  
      public function addNewCustomer() {
  
          $customer_name = $this-&gt;input-&gt;post('customer_name');
          $customer_address = $this-&gt;input-&gt;post('customer_address');
  
          $customerValue = array(
              'customer_name' =&gt; $customer_name, 
              'customer_address' =&gt; $customer_address
          );
  
          $addNewCustomer = $this-&gt;Permohonan_model-&gt;insertNewCustomerData($customerValue);
  
          if ($addNewCustomer === TRUE) {
              $data['response'] = true;
              echo json_encode($data);
  
          } else {
              $data['response'] = false;
              echo json_encode($data);
          }
  
      }
  
  }
  
  ?&gt;
  </code></pre>
  
  <p>And this is My Model : </p>
  
  <pre><code>&lt;?php
  /**
   * 
   */
  class Permohonan_model extends CI_Model {
  
      public function insertImageBarang($data = array()){
  
          $insert = $this-&gt;db-&gt;insert_batch('tb_image_barang', $data);
          return $insert?true:false;
  
      }
  
      public function insertNewRequestPesananBarang($pesananValue){
  
          $insert = $this-&gt;db-&gt;insert('tb_permohonan_pemesanan_barang', $pesananValue);
          return $insert?true:false;
  
      }
  
      public function insertNewCustomerData($customerValue){
  
          $insert = $this-&gt;db-&gt;insert('tb_customer', $customerValue);
          return $insert?true:false;
  
      }
  
      public function getCustomerData() {
          return $this-&gt;db-&gt;get('tb_customer')-&gt;result();
      }
  }
  ?&gt;
  </code></pre>
  
  <p>After run this app I got this error message : </p>
  
  <pre><code>java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
  </code></pre>
  
  <p>But I think my JSON response is correct, this is my JSON response after tried in Postman : </p>
  
  <pre><code>{
      "response": true
  }
  </code></pre>