Search code examples
androidkotlinretrofit2internal-server-error

500 Error code with "Internal server Error" message, while doing POST method using API in android application


For API confirmation, I have tried in POSTMAN app, But response is getting properly and the data has been inserted successfully. Below is the result of POSTMAN.

enter image description here

Also getting following errors in Logcat.

2021-06-01 17:56:58.522 16534-16534/? E/ample.addcours: Unknown bits set in runtime_flags: 0x8000
2021-06-01 17:56:58.893 1791-2057/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property
2021-06-01 17:56:58.897 1791-1897/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property
2021-06-01 17:57:01.325 1887-1887/? E/netmgr: Failed to open QEMU pipe 'qemud:network': Invalid argument
2021-06-01 17:57:01.713 1895-1895/? E/wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe

2021-06-01 17:57:48.882 1746-16596/? E/ResolverController: No valid NAT64 prefix (100, <unspecified>/0)
2021-06-01 17:57:48.915 2062-2154/system_process E/InputDispatcher: Window handle Window{33fd41d u0 com.example.addcourse/com.example.addcourse.RegisterActivity} has no registered input channel
2021-06-01 17:57:48.934 2062-6837/system_process E/InputDispatcher: Window handle Window{33fd41d u0 com.example.addcourse/com.example.addcourse.RegisterActivity} has no registered input channel 

As am new to android application. this is my first program using API concepts. Here is the code which I tried. Please guide me find the issue.

data class RegisterResponse(
    @SerializedName("status")
    val status: Int,
    @SerializedName("message")
    val message: String
)
 object ApiClient {

    // retrofit is HTTP client which can send request to API
    fun getRetrofit() : Retrofit {

        val retrofit = Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())  // this is used to automatically convert json string into java/kotlin object and java/kotlin object into json string whenever required
            .baseUrl("https://XXXX.com/XXXX/api/index.php/")

            .build()

        return retrofit
    }
}

interface ApiService { 
 //   @Headers("Content-type: application/json")
    @POST("Course/addCourse")
    @FormUrlEncoded

    fun signup(
        @Field("course_title") title: String,
        @Field("course_desc") desc: String,
        @Field("course_fees") fees: String
    ) : Call<RegisterResponse>

}

class RegisterActivity : AppCompatActivity() {
    lateinit var binding: ActivityRegisterBinding
    lateinit var retrofit: Retrofit
    lateinit var apiSerice: ApiService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityRegisterBinding.inflate(layoutInflater)
        setContentView(binding.root)
        retrofit = ApiClient.getRetrofit()
        apiSerice = retrofit.create(ApiService::class.java)
        binding.btnRegister.setOnClickListener {
            register()
        }
    }

    private fun register() {
        val title = binding.etCourseTitle.text.toString()
        val desc = binding.etCourseDescription.text.toString()
        val fees = binding.etCourseFee.text.toString()

        val call = apiSerice.signup(title, desc, fees)

        val progressDialog = ProgressDialog(this);
        progressDialog.setMessage("Please wait. We are processing your request")
        progressDialog.setCancelable(false)

        call.enqueue(object: Callback<RegisterResponse> {
            override fun onResponse(call: Call<RegisterResponse>, response: Response<RegisterResponse>) {

                progressDialog.dismiss()

                if(response.isSuccessful) {
                    val registerResponse: RegisterResponse? = response.body()
                    if(registerResponse?.status == 0) {
                        Toast.makeText(baseContext, "Registered successfully", Toast.LENGTH_LONG).show()
                    } else {
                        Toast.makeText(baseContext, registerResponse?.message, Toast.LENGTH_LONG).show()
                    }
                } else {
                    Toast.makeText(baseContext, response.message()+"/nSomething went wrong. Please retry.(1)", Toast.LENGTH_LONG).show()
                }
            }
            override fun onFailure(call: Call<RegisterResponse>, t: Throwable) {
                progressDialog.dismiss()
                Toast.makeText(baseContext, t.message+"Something went wrong. Please retry.(2)", Toast.LENGTH_LONG).show()
            }
        })
        progressDialog.show()
    }
}

Solution

  • Your API requires JSON data in the request body. But you're trying to send the data in the form FormURLEncoded.

    Create a data model class in Kotlin like below.

    data class Course(
    
        @SerializedName("course_title")
        val courseTitle: String,
    
        @SerializedName("course_desc")
        val courseDesc: String,
    
        @SerializedName("course_fees")
        val courseFees: String
    )
    

    And do the changes in ApiService.kt file

    interface ApiService { 
    
        @POST("Course/addCourse")
        fun signup(
           @Body data: Course
        ): Call<RegisterResponse>
    
    }
    

    In Activity or Fragment prepare the object of the Course class type and pass it to the signup() function.

    // rest of your code
    // .....
    val data = Course("Some course title", "Course desc", "150")
    
    val service = .....
    
    // call and pass parameter
    
    val call = serivce.signup(data)
    
    // handle response here