I want to send a request to an api with a URL that includes single quotation mark characters. I'm using retrofit2.
I want this url to reach to api: http://someapp.somecompany.com/api/contents/inc()?$filter=_Id%20eq%20'57fb60534421dd35544b27a9'
I tried #Query and #QueryMap annotations with (encoded=true) and also (encoded=false) properties but none of my tries worked.
MyClient (Interface)
#PUT("api/contents/inc()")
Call<Object> addLike(#QueryMap(encoded =true) Map<String,String> options);
MainActivity (Activity)
Map<String,String> likeMap = new HashMap<>();
likeMap.put("$filter","_Id%20eq%20'57fb60534421dd35544b27a9'");
Call<Object> addLikeCall = myClient.addLike(likeMap);
addLikeCall.enqueue(new Callback<Object>() {.....});
This code gives me this output:
--> PUT http://someapp.somecompany.com/api/contents/inc()?$filter=_Id%20eq%20%2757fb60534421dd35544b27a9%27 http/1.1 (0-byte body)
<-- 500 Internal Server Error http://someapp.somecompany.com/api/contents/inc()?$filter=_Id%20eq%20%2757fb60534421dd35544b27a9%27 (132ms, 36-byte body)
How can i avoid retrofit to encode my single quotation mark in url ?
Thanks.
You can replace the ' character in your url with %27 manually if it solves your proplem.
Other ascii encoding is in this link:
http://www.w3schools.com/TAGS/ref_urlencode.asp
Related
I am confused using retrofit with a PUT-Request containing path elements with a colon (":") in the var. It should change the colon to "%3A" but it doesn't and i get a 400 Error Response from the backend.
#PUT("/api/2/elements/{elementId}/features/{featureId}/options")
Call<String> updateThingRFIDTag(
#Header("api-token") String token,
#Header("Authorization") String base_auth,
#Path("elementId") String elemnentId,
#Path("featureId") String featureId,
#Body String optionTag
);
The Request URL looks like: https://pageurl.com/api/2/elements/com.element.d3:f4345-43234-5654d-33/features/com.featurelistings.powersign:1.0.0/options
When I use Postman the it works perfectly and the Request URL after hinting send looks the same except the colons(':') changed to '%3A'...
I already tried to use encode boolean = true in the path argument - doesn't help.
I already tried to change the base url an the path attr. before the request to '%3A'. But then retrofit encodes the '%3A' to soemthing else and I still get an error response. Can soemone help? I already work on this the last 3 days... Besides an http Interceptor doesn't help at all.
Thanks in advance!
Is it possible to send special characters in headers from okhttp library? Right now my app crashes showing the following error:
java.lang.IllegalArgumentException: Unexpected char 0xe5 at 1 in username value: påfyll
at okhttp3.Headers$Builder.checkNameAndValue(Headers.java:320)
This is how i am sending the request.
okhttp3.Request request = new okhttp3.Request.Builder()
.url(AppConfig.CONCERT_LIST)
.addHeader("Content-Type", "application/json; charset=UTF-8")
.addHeader("username", "påfulo")
.addHeader("accessToken", "12345ASDFGsf98")
.build();
It is not that simple, you will have to encode it and have your server to decode it.
You can find more information about this problem here :
https://github.com/square/okhttp/issues/2016
I think the best way to do it ASCII char rather then string.On the server you can get original value from it.
You can find your ASCII character down here-:
http://ee.hawaii.edu/~tep/EE160/Book/chap4/subsection2.1.1.1.html
I am using an API that is out of my control, as well having joined a development team recently that is using Retrofit1.
I am unable to send the request to the server in the format required, as the server requires multipart form data Body in the following format:
Uniqueidentifier:FileName.jpg:ReroutServerIP:Base64EncodedDocString.
I have tried many different techniques in order to accomplish this task but I cannot find any working method to do this. The server tells me that the message format not supported. Here is my current code (with the url stripped out). Please could someone assist?
#POST("URL")
public Response post_SendData(#Header("Content-Type") String ContentType, #Body String body);
In order to achieve the desired result, I can use postman with no headers and post a file from my system using the form-data post method. In the working postman post, the Key is the formatted string mentioned above and the value is a file selected from my desktop. Please see below for postman (edited to remove urls).
Postman
Thanks a lot guys.
If you want to send a file to the server :
public void uploadPictureRetrofit(File file, Callback<YourObject> response) {
// this will build full path of API url where we want to send data.
RestAdapter restAdapter = new RestAdapter
.Builder()
.setEndpoint(YOUR_BASE_URL)
.setConverter(new SimpleXMLConverter()) // if the response is an xml
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
// SubmitAPI is name of our interface which will send data to server.
SendMediaApiInterface api = restAdapter.
create(SendMediaApiInterface.class);
TypedFile typedFile = new TypedFile(MULTIPART_FORM_DATA, file);
api.sendImage(typedFile, response);
}
And this is the interface SendMediaApiInterface :
public interface SendMediaApiInterface {
#Multipart
#POST("url")
void sendImage(#Part("here_is_the_attribute_name_in_webservice") TypedFile attachments, Callback<YourObject> response);}
I'm trying to send a json post request to some API which in response sends a binary file back.
I'm doing well in Postman:
Header:
Body and result:
And I get the following code from Code section in Postman for Java/OKHTTP
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"Text\":\"Hello\",\r\n \"APIKey\":\"MY_API_KEY\",\r\n \"Speaker\":\"Female1\",\r\n \"Format\":\"mp3/32/m\",\r\n \"Quality\":\"quality/normal\"\r\n}");
Request request = new Request.Builder()
.url("http://url/CloudService/ReadText")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("cache-control", "no-cache")
.addHeader("postman-token", "0a1ce7c9-7a95-a2b9-7cde-8a7e6ce58386")
.build();
Response response = client.newCall(request).execute();
But when I use the above code in android it fails, I'm sure that I got Internet permission and the code is executed within an AsyncTask.
I'm not asking about the API or how to send json Post request to some API and get a binary file in response. I've used client.newCall(request).enqueue(new Callback(){//stuff here}); but none works. In response I got a 307 status code (instead of 200 in Postman) and no binary data at all. The API is very unclear and said nothing about the failure and I'm still working on that.
All I'm asking is that does Postman generates equivalent code for OkHttp correctly? and if not what is your suggestion for equivalent of this request in Java/OkHttp?
Just to provide another example, the following is also a working Python requests script to do the same job:
url = 'http://url/CloudService/ReadText'
api_key = 'MY_API_KEY'
body = {
'Text': 'Hello',
'Speaker': 'Female1',
'Format': 'mp3/32/m',
'Quality': 'quality/normal',
'APIKey': api_key
}
header = {
'Content-type': 'application/json'
}
r = requests.post(url, data=json.dumps(body), headers=header)
So after 3 days I found the problem, the server API did not mention that the URL endpoint must be ended with an / and even in their sample code they didn't use one.
It seems that both Postman and Python requests use an / at the end of URL in case of need, but Postman at least does not mention that in the generated equivalent code. Also OkHttp does not operate in the same manner.
However using a trailing / solved the problem.
I'm migrating my existing codebase to Retrofit 2, but having some trouble understanding the new syntax for Multipart requests. I'm also using Kotlin, although apart from a few syntax changes I think it shouldn't matter for this particular question.
Here's what I have right now:
val audioDuration = RequestBody.create(null, audioDuration.toString())
val file = RequestBody.create(MediaType.parse("audio/mp4"),
File(context.filesDir, filename).absoluteFile)
sendAudioChunk(audioDuration, file).enqueue(callback)
And here's the definition of the API:
#Multipart
#POST("path_to_request")
fun sendAudioChunk(#Part("duration") audioDuration: RequestBody,
#Part("audio") audioBlob: RequestBody) : Call<ResponseObject>
On Retrofit 1.9 I used TypedString and TypedFile for the request parameters, and now it seems one need to use RequestBody from OkHttp but I must be missing something since the request does not execute correctly.
I eventually figured it out. My web-service expects a filename for file uploads. This seems to be a work in progress support in the new Retrofit 2, but it is possible to circumvent the problem by adding it to the named parameter definition.
More details here : https://github.com/square/retrofit/issues/1140
One thing that is different is that TypedString would have a Content-Type of "text/plain; charset=UTF-8", where you are not setting a Context-Type at all for your audioDuration parameter. Try setting it to text/plain to get the same behavior as TypedString (charset will be set to utf-8 by default).
val audioDuration = RequestBody.create(MediaType.parse("text/plain"), audioDuration.toString())
If that doesn't work, you'll need to provide more information about how the "request does not execute correctly". A working request that you are trying to replicate would also be helpful.