I am a little confused as to which I am supposed to use.
The API is an trying to hit accepts regular text post parameters although its response is a JSON String.
Which should I use ?
You Can use JSON Object Request for this.
JsonObjectRequest and StringRequest is different in their parent class and their response. You could find it out if you dig into volley's source code.
JsonObjectRequest extends JsonRequest<JSONObject>
StringRequest extends Request<String>
So, if the response is a JSON String, then you could just use JsonObjectRequest for convenience, since Volley has wrapped the response to be a JSONObject.
StringRequest - when you want to send api parameter (getParams()) and fetch json response, you can use StringRequest.
JsonObjectRequest - When you only want to fetch the json response and not pass an api parameter, you can use JsonObjectRequest.
JsonObjectRequest can override the same set of methods (getHeaders(), getBodyContentType(), getBody(), getMethod()) like the StringRequest except getParams().
Related
I call a Rest API of salesforce by post method:
url = "https://test-dev-ed.my.salesforce.com/services/apexrest/AccountUsers/"
client = OkHttpClient()
val jsonIn = FormBody.Builder()
.add("email",URLEncoder.encode("dt1#gmail.com", "UTF-8"))
.add("password", URLEncoder.encode("1","UTF-8"))
.build()
request = Request.Builder()
.post(jsonIn)
.header("Authorization", "Bearer "+accesstoken)
.addHeader("Content-Type","application/x-www-form-urlencoded")
.url(url)
.build()
response = client.newCall(request).execute()
This is rest api:
#HttpPost
global static ID createUser(String email, String password) {
AccountUser__c us=new AccountUser__c();
us.Email__c=email;
us.Password__c=password;
us.Status__c=0;
insert us;
return us.Id;
}
But result return is error:
[{"errorCode":"UNSUPPORTED_MEDIA_TYPE","message":"Content-Type header specified in HTTP request is not supported: application/x-www-form-urlencoded"}]
I had try change application/json to application/x-www-form-urlencoded , but still can't resolve.
I try call a Get method, it is ok.
Why Post method occur error [Content-Type header specified in HTTP request is not supported]?
I would like to suggest a better resolution. Retrofit Library
Even though it is not mandatory to use Retrofit, these are few eye catchy aspects which makes it reliable and handy in similar use case of yours.
Why to use Retrofit?
Type-safe REST Adapter that makes common networking tasks easy
For POST operations, retrofit helps in assembling what needed to be submitted. Eg:- Generating URL encoded form.
Takes care of URL manipulation, requesting, loading, caching, threading, synchronization, sync/async calls
Helps to generate URL using type-aware generated code tied to specific REST API
Parsing JSON using GSON
Retrofit is an API adapter wrapped over OkHttp
The problem that you are facing can be resolved using retrofit like this.
public interface APIConfiguration{
#Headers({"Accept:application/json",
"Content-Type:application/x-www-form-urlencoded"})
#FormUrlEncoded
#POST("user/registration")
Observable<DataPojo> registrationAPI(#FieldMap(encoded = true) Map<String, String> params);
}
That's it, with few annotation the library takes care of Form URL
Encoding and related dependencies.
As it is inappropriate to start from corresponding Retrofit dependencies and sample code, you can go through Reference One and Reference Two for more details.
As per my understanding just checkout the difference the content type header "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
The content "multipart/form-data" follows the rules of all multipart MIME data streams.
https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
Also try your http request by setting your content type header as multipart/formdata.
How to Send post request using resttemplate in android in the following format?
{"UserInfo":{"Password":"TEST99","UserName":"TEST99"}}
hope to get a reply soon.
You should add something like this while sending request
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
and this well while making RequestBody
RequestBody body = RequestBody.create(JSON, json);
I think basically you want to convert encoding type to JSON.
Code you interface like this
#POST("yoururl")
Call<ResponseClass> someMethodName(#Body Example example );
Where You need to send Example class object and you can get Example clss by posting you jSON in http://www.jsonschema2pojo.org/
url:http://xxx.xxx.xxx/Order/Interface/V1/Polling?token=xxx¶m={"user":{"userID":2}}
post
token="xxx"
param="{"user":{"userID":2}}"
How to use Retrofit Post?
POST request parameters are not typed in the URL, they are typed on the body. For a request like that, you must use a GET request.
anyone know how can I send a JSON param to Volley ? Seeing the library, I watch the methods getParams that return a Map , but I need to send a Json with the form
{"medias" : [1,2,3,4,5] }
but if I send it with the getParams method, my server receive some like this : "medias" : "[1,2,3,4,5]" (the second part as a string)
any help?
A JsonObjectRequest in Volley allows you to pass your JSONObject into the constructor. Just create a JSONObject, add your JSONArray and use it to create your JsonObjectRequest.
Here's an example of how to create a JSONArray:
https://stackoverflow.com/a/13468303/736496
I'm trying to POST a JSONObject using the Retrofit library, but when I see the request at the receiving end, the content-length is 0.
In the RestService interface:
#Headers({
"Content-type: application/json"
})
#POST("/api/v1/user/controller")
void registerController(
#Body JSONObject registrationBundle,
#Header("x-company-device-token") String companyDeviceToken,
#Header("x-company-device-guid") String companyDeviceGuid,
Callback<JSONObject> cb);
And it gets called with,
mRestService.registerController(
registrationBundle,
mApplication.mSession.getCredentials().getDeviceToken(),
mApplication.mSession.getCredentials().getDeviceGuid(),
new Callback<JSONObject>() {
// ...
}
)
And I'm certain that the registrationBundle, which is a JSONObject isn't null or empty (the other fields are certainly fine). At the moment the request is made, it logs out as: {"zip":19312,"useAccountZip":false,"controllerName":"mine","registrationCode":"GLD94Q"}.
On the receiving end of the request, I see that the request has Content-type: application/json but has Content-length: 0.
Is there any reason why sending JSON in the body like this isn't working? Am I missing something simple in using Retrofit?
By default, you don't need to set any headers if you want a JSON request body. Whenever you test Retrofit code, I recommend setting .setLogLevel(RestAdapter.LogLevel.FULL) on your instance of RestAdapter. This will show you the full request headers and body as well as the full response headers and body.
What's occurring is that you are setting the Content-type twice. Then you're passing a JSONObject, which is being passed through the GsonConverter and mangled to look like {"nameValuePairs":YOURJSONSTRING} where YOURJSONSTRING contains your complete, intended JSON output. For obvious reasons, this won't work well with most REST APIs.
You should skip messing with the Content-type header which is already being set to JSON with UTF-8 by default. Also, don't pass a JSONObject to GSON. Pass a Java object for GSON to convert.
Try this if you're using callbacks:
#POST("/api/v1/user/controller")
void registerController(
#Body MyBundleObject registrationBundle,
#Header("x-company-device-token") String companyDeviceToken,
#Header("x-company-device-guid") String companyDeviceGuid,
Callback<ResponseObject> cb);
I haven't tested this exact syntax.
Synchronous example:
#POST("/api/v1/user/controller")
ResponseObject registerController(
#Body MyBundleObject registrationBundle,
#Header("x-company-device-token") String companyDeviceToken,
#Header("x-company-device-guid") String companyDeviceGuid);