How to Post Raw Whole Json in the Body of a Retrofit Request

Retrofit2 POST body as raw JSON

The error says that the body in not a valid JSON.

It was an expected response from server. Let's say below is your JSON body that you want to send,

{
"key_1" : "value 1",
"key_2" : "value 2",
}

When you use JsonObject#toString(), it'll become like this

{\"key_1\" : \"value 1\", \"key_2\" : \"value 2\"}

If you send above JSON data/body to the server, it'll be treated as normal String by the server.

Still you need to use toString() here because MediaType#parse() doesn't accept JsonObject parameters.

What's the solution?

As Ishan Fernando mentioned in his comment you need to create a custom POJO class to prepare the JSON body for the request. Or use HashMap to prepare the body.

Create POJO like below

import com.google.gson.annotations.SerializedName;

public class Data {

@SerializedName("Text")
private String text;

public Data(String text) {
this.text = text;
}

// getter and setter methods
}

And use it

Data data = new Data("text value to translate"); // construct object
Call<TranslationResultDTO> call = api.getTranslation(data); // change method parameter

And also adjust the method parameter in API interface

Call<TranslationResultDTO> getTranslation(@Body final Data text); // change method parameter

Edit 1

I went through the documentation attached to your question. I made a little mistake. JSON body should contain JSONArray, not JSONObject. Like below

[
{
"Text" : "text to translate"
}
]

Change method parameter to List<Data> in the API interface

Call<TranslationResultDTO> getTranslation(@Body final List<Data> text); // change method parameter

Use it like below

Data data = new Data("text value to translate"); // construct object
List<Data> objList = new ArrayList<>();
objList.add(data);
Call<TranslationResultDTO> call = api.getTranslation(objList); // change method parameter

Edit 2

And also API will respond with JSONArray. Sample response

[
{
"detectedLanguage": {
"language": "en",
"score": 1.0
},
"translations": [
{
"text": "Hallo Welt!",
"to": "de"
},
{
"text": "Salve, mondo!",
"to": "it"
}
]
}
]

Create below POJO classes to parse JSON response properly

Translation.java

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Translation {

@SerializedName("text")
@Expose
private String text;
@SerializedName("to")
@Expose
private String to;

// constructors, getter and setter methods

}

DetectedLanguage.java

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class DetectedLanguage {

@SerializedName("language")
@Expose
private String language;
@SerializedName("score")
@Expose
private float score;

// constructors, getter and setter methods

}

And finally, adjust TranslationResultDTO.java class like below.

import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class TranslationResultDTO {

@SerializedName("detectedLanguage")
@Expose
private DetectedLanguage detectedLanguage;
@SerializedName("translations")
@Expose
private List<Translation> translations = null;

// constructors, getter and setter methods

}

Interface class

Call<List<TranslationResultDTO>> call = api.getTranslation(objList);    // change method parameter

How to use POST method to send raw JSON using Retrofit in android

You can do like this first create a Pojo class like

class SendDataModel{

private String email;
private Name name;
private String password;

public String getEmail ()
{
return email;
}

public void setEmail (String email)
{
this.email = email;
}

public Name getName ()
{
return name;
}

public void setName (Name name)
{
this.name = name;
}

public String getPassword ()
{
return password;
}

public void setPassword (String password)
{
this.password = password;
}

@Override
public String toString()
{
return "ClassPojo [email = "+email+", name = "+name+", password = "+password+"]";
}
}

and other Pojo Class like

class Name{
private String lastName;

private String firstName;

public String getLastName ()
{
return lastName;
}

public void setLastName (String lastName)
{
this.lastName = lastName;
}

public String getFirstName ()
{
return firstName;
}

public void setFirstName (String firstName)
{
this.firstName = firstName;
}

@Override
public String toString()
{
return "ClassPojo [lastName = "+lastName+", firstName = "+firstName+"]";
}
}

and set your first and last name like

Name name = new Name();
name.setFirstName();
name.setLastName();
SendDataModel sendDatamodel=new SendDataModel();
sendDatamodel.setName(name);
sendDatamodel.setEmail("yourEmail")
sendDatamodel.setPassword("yourPassword");

and pass your sendDatamodel to your request.

Call<RegisterResponseModel> res = apiService.register(sendDatamodel);
res.enqueue(new Callback<RegisterResponseModel>() {
@Override
public void onResponse(Call<RegisterResponseModel> call,
Response<RegisterResponseModel> response) {

}

@Override
public void onFailure(Call<RegisterResponseModel> call, Throwable t)
{
// Log error here since request failed
Log.e(TAG, t.toString());
}
});

How to send raw json in request body

I think it caused you use camel case on your UserModel parameter (ex. dateOfBirth, maritalStatus) and your back end service try to parse key using underscore type (ex. date_of_birth, marital_status).

To keep using camel case in your dart file and underscore in json/back end service, you can use json_serializable and add JsonKey using underscore.
For example

import 'package:json_annotation/json_annotation.dart';
part 'user_model.g.dart';

@JsonSerializable()
class UserModel {
@JsonKey(name: 'first_name_ar')
String firstNameAr;
@JsonKey(name: 'middle_name_ar')
String middleNameAr;
@JsonKey(name: 'last_name_ar')
String lastNameAr;
@JsonKey(name: 'first_name_en')
String firstNameEn;
@JsonKey(name: 'middle_name_en')
String middleNameEn;
@JsonKey(name: 'last_name_en')
String lastNameEn;
@JsonKey(name: 'gender')
String gender;
@JsonKey(name: 'date_of_birth')
String dateOfBirth;
@JsonKey(name: 'marital_status')
String maritalStatus;


UserModel();
factory UserModel.fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
Map<dynamic, dynamic> toJson() => _$UserModelToJson(this);
}

I use this in my project to send raw json data using retrofit and works.

How to send JSON as Retrofit POST request

In your case you can use like this :

   val data = JSONObject()
val arr = JSONArray()
arr.put(inputText)
arr.put(steps)
arr.put(width)
arr.put(height)
arr.put(numberOfImages)
arr.put(diversityScale)
data.put("data", arr)

val map = ObjectMapper().readValue<MutableMap<Any, Any>>(data.toString())


@POST("your_url_here")
Call<Object> yourFunName(@Body Map<String, String> body)


Related Topics



Leave a reply



Submit