I tried to send data from android to my MySQL database using retrofit, but the data that was sent from android won't parsed into a php supported object so it doesn't inputted into the database. Turns out the api said that all of the parameters missing. So i presume the android sent the unsupported java object into my rest api. Here is my code :
Retrofit addBooking method :
private void addBooking(HashMap<String, String> booking){
Call<HashMap<String, String>> call = userService.addBooking(booking);
call.enqueue(new Callback<HashMap<String, String>>() {
@Override
public void onResponse(Call<HashMap<String, String>> call, Response<HashMap<String, String>> response) {
Log.i("RESPONSE", response.toString());
if(response.isSuccessful()){
//Toast.makeText(FormRuanganActivity.this, "Success!", Toast.LENGTH_SHORT).show();
Log.i("API RESPONSE", response.body().toString());
Snackbar.make(scrollViewForm, "Data successfully inputted", Snackbar.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<HashMap<String, String>> call, Throwable t) {
Log.e("ERROR: ", t.getMessage());
Toast.makeText(FormRuanganActivity.this, "ERROR: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
and here is my php api code :
case 'createBooking':
isParametersAvailable(array('title', 'start', 'end', 'nama', 'alamat', 'nohp', 'image', 'dosen',
'ruang', 'organisasi', 'alasan', 'mulai', 'selesai'));
$db = new dboperation();
$result = $db->createBooking(
$_POST['title'],
$_POST['start'],
$_POST['end'],
$_POST['nama'],
$_POST['alamat'],
$_POST['nohp'],
$_POST['image'],
$_POST['dosen'],
$_POST['ruang'],
$_POST['organisasi'],
$_POST['alasan'],
$_POST['mulai'],
$_POST['selesai']);
if($result){
$response['error'] = false;
$response['message'] = "Booking added!";
$response['bookings'] = $db->getBookings();
}
else{
$response['error'] = true;
$response['message'] = "Error occured!";
}
break;
Before using HashMap, i tried using my Booking object (i created from the model class), but it doesn't input the data to my database either. My question is how do i parse the object that the android send to the php rest api so the api can input the data to my database? thank you for your help
Here's the response i get in the log cat :
07-22 17:16:09.472 12761-12761/com.telkomuniversity.iflab.spriflab I/RESPONSE: Response{protocol=http/1.1, code=200, message=OK, url=xxxx}
07-22 17:16:09.472 12761-12761/com.telkomuniversity.iflab.spriflab I/HTTP RESPONSE: {message=Parameters title,start,end,nama,alamat,nohp,image,dosen,ruang,organisasi,alasan,mulai,selesai missing, error=true}
Editted ==
RetrofitCLient class :
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String url){
if(retrofit == null){
retrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
UserService interface :
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.FieldMap;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
public interface UserService {
@GET("api.php?apicall=getBookings")
Call<List<BookingInfo>> getBookings();
@POST("api.php?apicall=createBooking")
Call<HashMap<String, String>> addBooking(@Body HashMap<String, String> booking);
@PUT("api.php?apicall=updateStatus")
Call<BookingInfo> updateStatus(@Path("status") String status, @Body BookingInfo booking);
@DELETE("api.php?apicall=deleteBooking&={id}")
Call<BookingInfo> deleteBooking(@Path("id") int id);
}
and the create of the HashMap :
HashMap<String, String> params = new HashMap<>();
params.put("title", nim);
params.put("start", "10/16/2018");
params.put("end", "10/17/2018");
params.put("nama", name);
params.put("alamat", alamat);
params.put("nohp", hp);
params.put("image", "test.jpg");
params.put("dosen", dosen);
params.put("ruang", ruang);
params.put("organisasi", organisasi);
params.put("alasan", alasan);
params.put("mulai", waktuMulai);
params.put("selesai", waktuSelesai);
FormRuanganActivity class :
import android.app.DatePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.Toast;
import com.telkomuniversity.iflab.spriflab.ApiUtils.APIProperties;
import com.telkomuniversity.iflab.spriflab.ApiUtils.UserService;
import com.telkomuniversity.iflab.spriflab.Model.BookingInfo;
import com.telkomuniversity.iflab.spriflab.R;
import java.util.Calendar;
import java.util.HashMap;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class FormRuanganActivity extends AppCompatActivity implements View.OnClickListener{
// item dari layout
private EditText etNama, etNIM, etAlamat,etHP, etAlasan, etDosen, etOrganisasi;
private EditText etDate; // not editable
private Spinner spinnerRuangan, spinnerWaktuMulai, spinnerWaktuSelesai;
private Button btnDate, btnSubmit;
private ProgressBar progressBar;
private ScrollView scrollViewForm;
// isi spinner
private static final String[] itemSpinnerRuangan = {"IFLAB1", "IFLAB2", "IFLAB3",
"IFLAB4", "IFLAB5", "IKLAB1", "IKLAB2",};
private static final String[] itemSpinnerWaktuMulai = {"--Waktu Mulai--", "18:00:00", "18:30:00", "19:00:00",
"19:30:00", "20:00:00", "20:30:00", "21:00:00", "21:30:00", "22:00:00"};
private static final String[] itemSpinnerWaktuSelesai = {"--Waktu Selesai--", "18:00:00", "18:30:00", "19:00:00",
"19:30:00", "20:00:00", "20:30:00", "21:00:00", "21:30:00", "22:00:00"};
// datepicker variabel
private DatePickerDialog.OnDateSetListener dateListener;
// api properties
public static final int CODE_GET_REQUEST = 1024;
public static final int CODE_POST_REQUEST = 1025;
private UserService userService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_form_ruangan);
scrollViewForm = findViewById(R.id.scrollViewForm);
setTitle("Booking Form");
userService = APIProperties.getUserService();
progressBar = findViewById(R.id.progressBar);
etNama = findViewById(R.id.etNama);
etNIM = findViewById(R.id.etNIM);
etAlamat = findViewById(R.id.etAlamat);
etHP = findViewById(R.id.etHP);
etAlasan = findViewById(R.id.etAlasan);
etDosen = findViewById(R.id.etDosen);
etOrganisasi = findViewById(R.id.etOrganisasi);
etDate = findViewById(R.id.etDate);
btnDate = findViewById(R.id.btnDate);
btnSubmit = findViewById(R.id.btnSubmit);
btnDate.setOnClickListener(this);
btnSubmit.setOnClickListener(this);
spinnerRuangan = findViewById(R.id.spinnerRuangan);
ArrayAdapter<String> arrayAdpt = new ArrayAdapter<String>(FormRuanganActivity.this,
android.R.layout.simple_spinner_item, itemSpinnerRuangan);
arrayAdpt.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerRuangan.setAdapter(arrayAdpt);
spinnerRuangan.setSelection(0);
spinnerRuangan.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
// on progress
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
// on progress
}
});
spinnerWaktuMulai = findViewById(R.id.spinnerWaktuMulai);
ArrayAdapter<String> arrayAdptMulai = new ArrayAdapter<String>(FormRuanganActivity.this,
android.R.layout.simple_spinner_item, itemSpinnerWaktuMulai);
arrayAdptMulai.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerWaktuMulai.setAdapter(arrayAdptMulai);
spinnerWaktuMulai.setSelection(0);
spinnerWaktuMulai.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//on progress
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
//on progress
}
});
spinnerWaktuSelesai = findViewById(R.id.spinnerWaktuSelesai);
ArrayAdapter<String> arrayAdptSelesai = new ArrayAdapter<String>(FormRuanganActivity.this,
android.R.layout.simple_spinner_item, itemSpinnerWaktuSelesai);
arrayAdptSelesai.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerWaktuSelesai.setAdapter(arrayAdptSelesai);
spinnerWaktuSelesai.setSelection(0);
spinnerWaktuSelesai.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//on progress
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
//on progress
}
});
dateListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int year, int month, int day) {
try {
month = month + 1;
String date = day + "-" + month + "-" + year;
etDate.setText(date);
}
catch(Exception e){
Toast.makeText(FormRuanganActivity.this, "Error Occurred", Toast.LENGTH_SHORT).show();
}
}
};
}
@Override
public void onClick(View view) {
if(view == btnSubmit){
try {
//Toast.makeText(FormRuanganActivity.this, "Under Maintenance", Toast.LENGTH_SHORT).show();
createBooking();
} catch(Exception e){
e.printStackTrace();
Toast.makeText(FormRuanganActivity.this, "Exception detected" , Toast.LENGTH_SHORT).show();
}
}
else if(view == btnDate){
try {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(FormRuanganActivity.this,
android.R.style.Theme_Holo_Light_Dialog_MinWidth,
dateListener,
year, month, day);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
} catch (Exception e){
Toast.makeText(FormRuanganActivity.this, "Exception detected!", Toast.LENGTH_SHORT).show();
}
}
}
private void createBooking(){
String name = etNama.getText().toString().trim();
String nim = etNIM.getText().toString().trim();
String alamat = etAlamat.getText().toString().trim();
String hp = etHP.getText().toString().trim();
String alasan = etAlasan.getText().toString().trim();
String dosen = etDosen.getText().toString().trim();
String organisasi = etOrganisasi.getText().toString().trim();
String ruang = spinnerRuangan.getSelectedItem().toString();
String waktuMulai = spinnerWaktuMulai.getSelectedItem().toString();
String waktuSelesai = spinnerWaktuSelesai.getSelectedItem().toString();
String tanggal = etDate.getText().toString().trim();
int spn1 = spinnerWaktuMulai.getSelectedItemPosition();
int spn2 = spinnerWaktuSelesai.getSelectedItemPosition();
if(TextUtils.isEmpty(name)){
etNama.setError("Silahkan masukkan nama anda.");
etNama.requestFocus();
return;
}
else if(TextUtils.isEmpty(nim)){
etNIM.setError("Silahkan masukkan NIM anda.");
etNIM.requestFocus();
return;
}
else if(TextUtils.isEmpty(alamat)){
etAlamat.setError("Silahkan masukkan alamat anda.");
etAlamat.requestFocus();
return;
}
else if(TextUtils.isEmpty(hp)){
etHP.setError("Silahkan masukkan Nomor HP anda.");
etHP.requestFocus();
return;
}
else if(TextUtils.isEmpty(alasan)){
etAlasan.setError("Silahkan masukkan alasannya.");
etAlasan.requestFocus();
return;
}
else if(TextUtils.isEmpty(dosen)){
etDosen.setError("Silahkan masukkan nama dosen penanggung jawabnya.");
etDosen.requestFocus();
return;
}
else if(TextUtils.isEmpty(organisasi)){
etOrganisasi.setError("Silahkan masukkan nama organisasi anda.");
etOrganisasi.requestFocus();
return;
}
else if(TextUtils.isEmpty(tanggal)){
etDate.setError("Silahkan masukkan tanggal peminjaman.");
etDate.requestFocus();
return;
}
else if(spn1 == 0){
Toast.makeText(FormRuanganActivity.this, "Waktu Mulai harap diisi", Toast.LENGTH_SHORT).show();
spinnerWaktuMulai.requestFocus();
}
else if(spn2 == 0){
Toast.makeText(FormRuanganActivity.this, "Waktu Selesai harap diisi", Toast.LENGTH_SHORT).show();
spinnerWaktuSelesai.requestFocus();
}
// tanggal start sama end nya masih fix di tanggal ini belom dirubah jadi editable
HashMap<String, String> params = new HashMap<>();
params.put("title", nim);
params.put("start", "10/16/2018");
params.put("end", "10/17/2018");
params.put("nama", name);
params.put("alamat", alamat);
params.put("nohp", hp);
params.put("image", "test.jpg");
params.put("dosen", dosen);
params.put("ruang", ruang);
params.put("organisasi", organisasi);
params.put("alasan", alasan);
params.put("mulai", waktuMulai);
params.put("selesai", waktuSelesai);
BookingInfo b = new BookingInfo();
b.setNim(nim);
b.setTanggalmulai("10/16/2018");
b.setTanggalselesai("10/17/2018");
b.setNama(name);
b.setAlamat(alamat);
b.setNohp(hp);
b.setImage("image.jpg");
b.setDosen(dosen);
b.setRuangan(ruang);
b.setOrganisasi(organisasi);
b.setAlasan(alasan);
b.setWaktumulai(waktuMulai);
b.setWaktuselesai(waktuSelesai);
addBooking(params);
}
private void addBooking(HashMap<String, String> booking){
Call<HashMap<String, String>> call = userService.addBooking(booking);
call.enqueue(new Callback<HashMap<String, String>>() {
@Override
public void onResponse(Call<HashMap<String, String>> call, Response<HashMap<String, String>> response) {
Log.i("RESPONSE", response.toString());
if(response.isSuccessful()){
//Toast.makeText(FormRuanganActivity.this, "Success!", Toast.LENGTH_SHORT).show();
Log.i("API RESPONSE", response.body().toString());
Snackbar.make(scrollViewForm, "Data successfully inputted", Snackbar.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<HashMap<String, String>> call, Throwable t) {
Log.e("ERROR: ", t.getMessage());
Toast.makeText(FormRuanganActivity.this, "ERROR: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
error log :
07-22 18:54:55.142 14250-14250/com.telkomuniversity.iflab.spriflab E/ERROR:: Expected a string but was BEGIN_ARRAY at line 1 column 55 path $.
@FieldMapinstead of@Bodyonce and check.@FormUrlEncodedabove@POST("api.php?apicall=createBooking")and check