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
How to Scroll Scrollview to Bottom Programmatically in Android
Prevent Screen Rotation on Android
How to Display an Image in Full Screen on Click in the Imageview
Where Is Android_Sdk_Root and How to Set It.
Adb Is Not Detecting My Android Device on Ubuntu
Android: Open a Pdf from My App Using the Built in Pdf Viewer
How to Check Miui Autostart Permission Programmatically
App Crashes (Sometimes) With Fatal Signal 11 (Sigsegv), Code 1
How to Refresh a Previous Activity After the Back Button Is Pressed
How to Center the Elements in Constraintlayout
Scrollview Not Scrolling in Android Bottomsheet
How to Completely Rename an Android Application
How to Make Push Notification With Specific Sound
How to Resolve Javax.Xml.Bind.Jaxbcontext in Eclipse