android retrofit post request request body as raw JSON - android

This is my first time using the retrofit in android (Java) and i don't know how to do post api
in postman i use Request Body as raw JSON
{
"description": "aaaaaa",
"reportedpriority_description": "Elevé",
"reportedby": "zz",
"assetnum": "111",
"affectedperson": "ahmed"
}
someone can help me with example of code? it return empty response body

void requestcall(){
try
{
HashMap respMap = new HashMap<>();
respMap.put("Key1", "Value1");
respMap.put("Key2", "Value2");
respMap.put("Key3", "Value3");
String resultString = convertToJson(respMap);
sendToServer(resultString);
}
catch (Exception e)
{ }
}
public static String convertToJson(HashMap<String, String> respMap)
{
JSONObject respJson = new JSONObject();
JSONObject respDetsJson = new JSONObject();
Iterator mapIt = respMap.entrySet().iterator();
try
{
while (mapIt.hasNext()) {
HashMap.Entry<String, String> entry = (HashMap.Entry) mapIt.next();
respDetsJson.put(entry.getKey(), entry.getValue());
}
//change according to your response
respJson.put("RESPONSE", respDetsJson);
}
catch (JSONException e)
{
return "";
}
return respJson.toString();
}

There are two ways you can send a body for Post methods, you can either create a JSON string in the format you want. Or you can simply create a model class with the same field names as your JSON keys, and then initialize values to them while sending a request.
Model class:
class Example {
var description: String? = null
var reportedpriority_description: String? = null
var reportedby: String? = null
var assetnum: String? = null
var affectedperson: String? = null
}
Init values:
val obj = Example()
obj.description = "aaaaaa"
// and so on
You can then pass the object to your POST method.
You can refer to documentations to learn how to code the API methods.
Hope this works for you!

Related

JSONArray cannot be converted to JSONObject Value ["1"]

I have created JSONRequest by using volley ussing this tutorial https://www.tutorialspoint.com/how-to-use-volley-library-to-parse-json-in-android-kotlin-app
Blynk APi returns this "1"
i have this error Caused by: org.json.JSONException: Value ["1"] of type org.json.JSONArray cannot be converted to JSONObject
private fun jsonParse() {
val url = "http://blynk-cloud.com/4ae3851817194e2596cf1b7103603ef8/get/D8"
val request = JsonObjectRequest(Request.Method.GET, url, null, { response ->
try {
val JSONObject = response.getJSONArray("test")
for (i in 0 until JSONObject.length()) {
val test = JSONObject.getJSONObject(i)
val status = test.getString("test1")
textView.append("$status")
}
} catch (e: JSONException) {
e.printStackTrace()
}
}, { error -> error.printStackTrace() })
requestQueue?.add(request)
}
Obviously, the response JSON string is not correct. I checked the JSON string with the Url on Firefox, it shows:
Use this style JSON to test is nonsense, I think. If you want to test parsing JSON with Volley lib, you can use public API to test it.

Gson toJson returning string of JSON instead of JSON Object

The Class that I'm using with toJson
class LoadUserDTO: Serializable {
#SerializedName("userGuid")
var userGuid: String? = null
#SerializedName("userToken")
var userToken: String? = null
constructor(userGuid: String, userToken: String) {
this.userGuid = userGuid
this.userToken = userToken
}
}
And the rest of the use:
val payload = LoadUserDTO(userGuid = user.guid!!, userToken = user.token!!)
val jsonPayload = Gson().toJson(payload)
this.socketService.socket.emit(EndpointsEnum.AppLoadUser, jsonPayload)
The jsonPayload should be a JSON Object. Instead, the entire thing is a String of what should be a JSON Object:
"{"userGuid":"...","userToken":"..."}"
When this is received by the server, it's not receiving a JSON Object as the Web UI or Swift App sends, but is instead just a String, not converted to a JSON Object.
try this,
var jsonString = """{"id":1,"description":"Test"}""";
var testModel = gson.fromJson(jsonString, TestModel::class.java)
Based on your requirement instead using Gson you may use String.format to achieve this by one line of code -
// val payload = LoadUserDTO(userGuid = user.guid!!, userToken = user.token!!)
// val jsonPayload = Gson().toJson(payload)
val jsonPayload = String.format("\"{\"userGuid\": \"%s\"," + "\"userToken\": \"%s\"" + "}\"",user.guid,user.token)
// Log.d("ZI",jsonPayload)
Output- example
"{"userGuid": "1234","userToken": "token000"}"
You may remove space after : while formatting string .
val jsonPayload = String.format("\"{\"userGuid\":\"%s\"," + "\"userToken\":\"%s\"" + "}\"",user.guid,user.token)
Output-
"{"userGuid":"1234","userToken":"token000"}"
I don't fully understand why yet, but this SO Question gave me the answer for it to work:
Send JSON data from in socket.io from android
val jsonPayload = Gson().toJson(payload)
val jsonObj = JSONObject(jsonPayload)
this.socketService.socket.emit(EndpointsEnum.AppLoadUser, jsonObj)
After making the jsonObj the server now has a properly formed JSON Object that it can work with.

How can I pass the param and value to post api using retrofit in android?

#Headers("Content-Type: application/json")
#POST("answer")
fun sendAnswer(#Header("token") token :String, #Body answer: SendAnswerModel):Call<SendAnswerResultModel>
here is my model class
data class Vote2019Answer(
#SerializedName("question_id") #Expose val id: Int,
#SerializedName("answer") #Expose val answer: String)
another model class
data class SendAnswerModel(
#SerializedName("answer") #Expose val answer: List<Vote2019Answer> )
You can pass json object / json array using #Body by converting the json model to POJO ( using GSON) .
Check this out !
Try the following way.
Your API endpoint
#POST("url")
Call<ResponseBody> yourAPi(#Body JSONArray jsonArray);
And API call using param data
String[] answer = {"aaa","bbb","ccc"}
JSONArray jsArray= new JSONArray();
try {
for(int i = 0; i < answer.length; i++) {
JSONObject object = new JSONObject();
object.put("question_id",i+1);
object.put("answer",answer[i]);
jsArray.put(object);
}
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// here you can call your api
Call<ResponseBody> call = yourApiService.yourAPi(jsArray);
// ........

Unable to parse json response with html tags

I am trying to parse json response which have Html tags and getting invalid json exception, I tried this Android JSON parsing with HTML tags but unfortunately no success and now I am using Jsoup.parse() reference but still getting exception
Here is my json response :
https://i.stack.imgur.com/HajiV.png
and here is my Kotlin code to parse json using Jsoup
if (response != null) {
var jsonObject: JSONObject? = null
var dataStr = Jsoup.parse(response.string()).text()
if (!TextUtils.isEmpty(dataStr)) {
jsonObject = JSONObject(dataStr)
var d = jsonObject.getJSONObject("d")
var result = d.getJSONObject("result")
var dataArr = result.getJSONArray("InformativeContent")
for (position in 0 until dataArr.length()) {
var dataObj: JSONObject = dataArr.getJSONObject(position)
var infoPageObj: JSONObject = dataObj.getJSONObject("InfoPage")
var infoPage = InfoPage(
infoPageObj.getString("Header"),
infoPageObj.getString("Heading"),
infoPageObj.getString("IsHTML"),
infoPageObj.getString("Message"))
introContentList!!.add(infoPage)
}
/**
* update viewPager UI
*/
settingUpPager()
}
}
Please let me know the issue
var infoPageObj: JSONObject = dataObj.getJSONObject("InfoPage") I think this is wrong. according to your image `InfoPage` is a jsonArray.
You are accessing value in wrong order.
In json response "InfoPage" return JSONArray which consist JSON Object of type InfoPage("Header","Heading","isHTML","Message")
for (position in 0 until dataArr.length()) {
var dataObj: JSONObject = dataArr.getJSONObject(position)
var infoPageObj: JSONArray = dataObj.getJSONObject("InfoPage")
for (infoPageposition in 0 until infoPageObj.length()) {
var infoPageJSONObj: JSONObject = dataArr.getJSONObject(infoPageposition)
var infoPage = InfoPage(
infoPageJSONObj.getString("Header"),
infoPageJSONObj.getString("Heading"),
infoPageJSONObj.getString("IsHTML"),
infoPageJSONObj.getString("Message"))
introContentList!!.add(infoPage)
}
}

set DeviceToken in parse for Android

i can't set the device token in Installation table using parse
im using
ParseInstallation installation =ParseInstallation.getCurrentInstallation();
installation.put("GCMSenderId",senderId);
installation.put("pushType","gcm");
installation.put("deviceToken",token);
but when i try to use save i got an exception.
Cannot modify `deviceToken` property of an _Installation object. android
The problem is, the backend use this tokenId to send the push notification for another provider (OneSignal), so im wondering if its any way to write in the deviceToken row (As far as i know this is for iOS only).
i need write in the deviceToke the GCM token i receive.
Thanks
I solved this by adding a Parse Cloud function called setDeviceToken. This way I can use the MasterKey to modify the Installation record.
Parse.Cloud.define("setDeviceToken", function(request, response) {
var installationId = request.params.installationId;
var deviceToken = request.params.deviceToken;
var query = new Parse.Query(Parse.Installation);
query.get(installationId, {useMasterKey: true}).then(function(installation) {
console.log(installation);
installation.set("deviceToken", deviceToken);
installation.save(null, {useMasterKey: true}).then(function() {
response.success(true);
}, function(error) {
response.error(error);
})
}, function (error) {
console.log(error);
})
});
Then, in my Android app's Application.onCreate:
OneSignal.idsAvailable(new OneSignal.IdsAvailableHandler() {
#Override
public void idsAvailable(String userId, String registrationId) {
final ParseInstallation currentInstallation = ParseInstallation.getCurrentInstallation();
if (registrationId != null) {
HashMap<String, Object> params = new HashMap<>(2);
params.put("installationId", currentInstallation.getObjectId());
params.put("deviceToken", registrationId);
ParseCloud.callFunctionInBackground("setDeviceToken", params, new FunctionCallback<Boolean>() {
#Override
public void done(java.lang.Boolean success, ParseException e) {
if (e != null) {
// logException(e);
}
}
});
}
}
});
For future visitors, I solved this a different way, by using the Parse Rest API: http://parseplatform.org/docs/rest/guide/
Using that, you can bypass the regular SDK limitations. Just make a put request to https://yourApp/parse/installtions/{installationObjectIDHere}. make a dictionary and encode it as JSON:
Map<String, String> dictionary = new HashMap<String, String>();
dictionary.put("deviceToken", yourToken);
JSONObject jsonDictionary = new JSONObject(dictionary);
String bodyAsString = jsonDictionary.toString();
RequestBody body = RequestBody.create(JSON, bodyAsString);
then send the request, and that should work.
joey showed the right way to do that, the extra part i added is about the authentication header.
This is what i did:
val JSON = MediaType.parse("application/json; charset=utf-8")
val client = OkHttpClient()
val installationObjectId = ParseInstallation.getCurrentInstallation().objectId
val myAppId = getString(R.string.parse_app_id)
val key = getString(R.string.parse_client_key)
val server = getString(R.string.parse_server_url)
val mRequestUrl = "$server/installations/$installationObjectId"
val dictionary = HashMap<String, String?>()
dictionary["deviceToken"] = myToken
val jsonDictionary = JSONObject(dictionary)
val bodyAsString = jsonDictionary.toString()
val body = RequestBody.create(JSON, bodyAsString)
val request = Request.Builder()
.url(mRequestUrl)
.put(body)
.addHeader("X-Parse-Application-Id", myAppId)
.addHeader("X-Parse-Client-Key", key)
.build()
client.newCall(request).execute()

Categories

Resources