Reputation: 47
I am working on my android app for which i am using POST request I am getting 400 bad request error
I think maybe their is a model class error i am not sure please respond
RetrofitInstance
public class RetrofitInstance {
private static Retrofit retrofit = null;
private static String BASE_URL = "http://<your ip address>:3000/";
public static Retrofit getService(){
Gson gson = new GsonBuilder()
.setLenient()
.create();
if(retrofit == null){
retrofit = new Retrofit
.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
API END POINT
public interface EndPoints {
@FormUrlEncoded
@POST("api/movie")
Call<Movie> setMovie(@Field("title") String title,
@Field("genreId") String genreId,
@Field("numberInStock") int numberInStock,
@Field("dailyRentalRate") int dailyRentalRate);
}
POSTMAN REQUEST AND RESPONSE FOR TESTING THAT API IS WORKING https://ibb.co/TkvDZFz
MODEL CLASS
Genre Pojo:
public class Genre{
@SerializedName("name")
private String name;
@SerializedName("_id")
private String id;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setId(String id){
this.id = id;
}
public String getId(){
return id;
}
@Override
public String toString(){
return
"Genre{" +
"name = '" + name + '\'' +
",_id = '" + id + '\'' +
"}";
}
}
Movie POJO :
public class Movie{
@SerializedName("dailyRentalRate")
private int dailyRentalRate;
@SerializedName("__v")
private int V;
@SerializedName("genre")
private Genre genre;
@SerializedName("_id")
private String id;
@SerializedName("title")
private String title;
@SerializedName("numberInStock")
private int numberInStock;
@SerializedName("genreId")
private String genreId;
public Movie(String title, String genreId, int numberInStock ,int dailyRentalRate) {
this.dailyRentalRate = dailyRentalRate;
this.title = title;
this.numberInStock = numberInStock;
this.genreId = genreId;
}
public void setDailyRentalRate(int dailyRentalRate){
this.dailyRentalRate = dailyRentalRate;
}
public int getDailyRentalRate(){
return dailyRentalRate;
}
public void setV(int V){
this.V = V;
}
public int getV(){
return V;
}
public void setGenre(Genre genre){
this.genre = genre;
}
public Genre getGenre(){
return genre;
}
public void setId(String id){
this.id = id;
}
public String getId(){
return id;
}
public void setTitle(String title){
this.title = title;
}
public String getTitle(){
return title;
}
public void setNumberInStock(int numberInStock){
this.numberInStock = numberInStock;
}
public int getNumberInStock(){
return numberInStock;
}
@Override
public String toString(){
return
"Movie{" +
"dailyRentalRate = '" + dailyRentalRate + '\'' +
",__v = '" + V + '\'' +
",genre = '" + genre + '\'' +
",_id = '" + id + '\'' +
",title = '" + title + '\'' +
",numberInStock = '" + numberInStock + '\'' +
"}";
}
}
Activity
public class MainActivity extends AppCompatActivity {
private Button click;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
click = findViewById(R.id.click);
click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addMovieCall();
}
});
}
private void addMovieCall() {
final EndPoints vidlyEndPoint = RetrofitInstance.getService().create(EndPoints.class);
Call<Movie> call = vidlyEndPoint.setMovie("intelRPG","5d7398d2bdc4d04960d60845",20,30);
call.enqueue(new Callback<Movie>() {
@Override
public void onResponse(Call<Movie> call, Response<Movie> response) {
if(!response.isSuccessful()){
Log.e("Response", String.valueOf(response.code()));
Log.e("Response", String.valueOf(response.message()));
}
else if(response.isSuccessful()){
Log.e("Response", String.valueOf(response.body().getId()));
Log.e("Response", String.valueOf(response.body().getTitle()));
Log.e("Response", String.valueOf(response.body().getGenre().getName()));
Log.e("Response", String.valueOf(response.body().getDailyRentalRate()));
Log.e("Response", String.valueOf(response.body().getNumberInStock()));
Toast.makeText(getApplicationContext(),"Posted Successfully",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<Movie> call, Throwable t) {
Log.e("Response failed",t.getMessage());
}
});
}
}
I expect the output of 200, but the actual output is 400.
Upvotes: 2
Views: 147
Reputation: 3930
You can try like below.
JsonObject requestBody = new JsonObject();
requestBody.addProperty("title", "intelRPG");
requestBody.addProperty("genreId", "5d7398d2bdc4d04960d60845");
requestBody.addProperty("numberInStock", "20");
requestBody.addProperty("dailyRentalRate", "30");
Call<Movie> call = vidlyEndPoint.setMovie(requestBody);
.....
API END POINT should be like below
@POST("api/movie")
Call<Movie> setMovie(@Body JsonObject jsonObject);
Upvotes: 0
Reputation: 1090
You have to make your values the same type as the required
@FormUrlEncoded
@POST("api/movie")
Call<Movie> setMovie(@Field("title") String title,
@Field("genreId") String genreId,
@Field("numberInStock") String numberInStock,
@Field("dailyRentalRate") String dailyRentalRate);
}
I would also suggest using One pojo class with @Body
annotation.
By the way, to understand the network problem better, You'd better use chuck library, by just adding the Chuck as an Intercepter in okhttp object. It will show the real cause, help you to find the problem faster
https://github.com/jgilfelt/chuck
Upvotes: 3
Reputation: 6919
Change your interface call :
Call<Movie> setMovie(@Field("title") String title,
@Field("genreId") String genreId,
@Field("numberInStock") String numberInStock, // Needs String
@Field("dailyRentalRate") String dailyRentalRate);
}
and call will be :
Call<Movie> call = vidlyEndPoint.setMovie("intelRPG","5d7398d2bdc4d04960d60845","20","30");
Upvotes: 1