Retrofit URL Problem using PUT-Request with colon in Path - android

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!

Related

Can't PUT from Android to DJANGO REST

I have a DJANGO REST server on my personal network that is set up to get and receive JSON strings to update "statuses" for a project I'm working on. I can GET the information down into my Android application just fine but when I try to PUT information up to the server, I get the error:
Bad Request: /api/users/1/
[28/Oct/2019 21:23:23] "PUT /api/users/1/ HTTP/1.1" 400 107
I think it's the app because I can successfully do a PUT request via Windows Powershell, but it doesn't work on the Android app. Here is the code using the OKHTTP class:
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String content = String.format("{'status':%s}", selectedStatus);
RequestBody body = RequestBody.create(JSON, content);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(IPAddress + "api/users/" + currentUserID + "/")
.addHeader("Content-Type", "application/json")
.put(body) //PUT
.build();
client.newCall(request).execute();
I have tried using the standard HttpURLConnection class, which is what I did for the GET method, but I don't even get a response from the server when I do that. I've tried about a dozen ways to PUT something to the server, but nothing has worked. Any help achieving this goal would be appreciated. Thanks.
For anyone looking at this later, I found the issue. It turns out that in the Windows Powershell, you can use single quotes in the JSON string, but you NEED to use double quotes with the OKHTTP methods. Thus, I changed:
String content = String.format("{'status':%s}", selectedStatus);
to:
String content = String.format("{\"status\":%s}", selectedStatus);
and everything went through perfectly. Hope this helps someone.

Retrofit 1, sending multipart form data with custom key for value

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);}

Retrofit 500 internal server error

I have a post registration webserivce as the following
#FormUrlEncoded
#POST("register/default")
Observable<BaseResponse> doRegistration(#Field("name") String name,#Field(value = "email",encoded = true) String email,#Field("phone_number") String phone_number,#Field("password") String password,#Field("password_confirmation") String password_confirmation);
I've tried with postman to consume this service , and it replies with the response of registration , from android side it causes an exception (500 internal server error ) ,
when and only using a symbol # on the email field , also i've tried the encode option flag mentioned above, UTF-8 encoding but it doesn't interpreted as an email by server side.
is there is a retrofit related issue !
It was a server related issue on creating new record so larvae returns the default exception response with internal server error.

How to avoid Retrofit to encode single quotation mark in HTTP Url?

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

Retrofit 2 Multipart requests

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.

Categories

Resources