How can I send non-ascii characters as a query parameter
without encoding it as ascii with retrofit (assuming thats whats happening)?
For example I dont want the value of the query q to go from /?q=Gä to /?q=G%C3%A4 when it arrives at the server end.
#GET("endpoint/")
fun get(
#Query("q") value: String,
): Response
I have tried using #Query(value = "q", encoded=true) though I dont think that does what I initially thought it would.
I also want to mention that I can send this request in my firefox browser and it works correctly.
Non-ASCII Header Encoding Issues #891 (though about the header)
Related
Implementing profile modification. The function has the ability to request values for image change and nickname change to the server, and the server hands over the modified nickname value and the value of the base64 decoded image to the response value. There is a problem implementing the feature, where the value of the image is answered correctly, but the value of the modified nickname is not a pure string value, but contains odd double quotation and backslash values. What is wrong with that?
This is all code i coded
This is result from Log:
resultCode : CNAPResponse(nickname="abcdefg", image=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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
This is also result but from Postman:
In the sharedPreference file, values seem to be stored properly in the form of a string, but when the response values are checked with log and postman, the nickname values among the response values differ from each other, especially postman, and the nickname values include double quotes and backslashes.
How can I fix it?
I'm using Kotlin and retrofit in my Android App to call API's, but some of the API URLs have these characters in them: ^, #, ~.
I'm using the GET API method. My host URL does not have special / strange characters in them nor does my API method names, but the API methods that I've set up; have a few parameters; and sometimes the arguments I'm sending, when calling the API methods, have these special characters in them.
In those cases I'm not getting a response back and the API call fails.
I've noticed that retrofit changes my URL. It replaces any special character with 3 other characters. I've tested my URLs directly in a browser and in Postman, and they work fine.
Is there something specific I have to do in Kotlin to make retrofit be OK with my special characters?
try this
import java.net.URLEncoder
fun main(args: Array<String>) {
val url = "http://foo bar/"
println(URLEncoder.encode(url, "utf-8")) // note: encodes space to + not %20
}
Output:
http%3A%2F%2Ffoo+bar%2F
You should avoid Special character in Api
URL encoding is often required to convert special characters (such as "/", "&", "#", ...), because special characters:
1. Have special meaning in some contexts, or
2. Are not a valid character for an URL, or
3. could be altered during the transfer.
For instance, the "#" character needs to be encoded because it has a special meaning of that of an HTML anchor.
The character needs to be encoded because it is not a valid URL character. Also, some characters, such as "~" might not transport properly across the internet. Instead of proceeding with the complex process you should focus on correcting the old one.
More you can read here.
I am very much new to android and I was studying the Retrofit 2 for networking, to send the Get why we are use the Query parameter?
It is not necessary to send Query Parameters with GET requests. It is something related to how the end point is configured on the API you are trying to consume.
While designing APIs especially GET methods certain parameters can be kept optional by specifying them as query parameters.
#GET("location")
Response getUser(#QueryParam("name") String name);
can be called by both
/location
/location?name=test
Query Parameter is not merely confined to GET requests. It can be used with other methods too e.g., DELETE, etc.
This is a concept related to HTTP methods
Retrofit uses annotations to translate defined keys and values into appropriate format. Using the #Query("key") String value annotation will add a query parameter with name key and the respective string value to the request url (of course you can use other types than string :)).
Actually, there are APIs with endpoints allowing you to pass (optionally) multiple query parameters. You want to avoid a service method declaration like the one below with “endless” options for request parameters:
public interface NewsService() {
#GET("/news")
Call<List<News>> getNews(
#Query("page") int page,
#Query("order") String order,
#Query("author") String author,
#Query("published_at") Date date,
…
);
}
You could call the .getNews service method with null values for each of the parameters to make them optional. Retrofit will ignore null values and don’t map them as query parameters. However, there is a better solution to work with complex API endpoints having various options for query parameters. Don’t worry, Retrofit got you covered!
You can explore more from the given link below:-
https://futurestud.io/tutorials/retrofit-2-add-multiple-query-parameter-with-querymap
Lets say you have following api to call:
https://api.themoviedb.org/3/movie/now_playing/api_key=1
So for you to pass the value for "api_key" dynamically, you should use #Query("api_key") as:
#GET("movie/now_playing")
Call<MovieData> getMovieData(#Query("api_key") String apiKey);
So here is a simple way to understand it for those that might want to use Retrofit query. Please check as follows ....
If you specify #GET("Search?one=5"), then any #Query("two") must be appended using &, producing something like Search?one=5&two=7.
If you specify #GET("Search"), then the first #Query must be appended using ?, producing something like Search?two=7.
That's how Retrofit works.
When you specify #GET("Search?"), Retrofit thinks you already gave some query parameter, and appends more query parameters using &.
Remove the ?, and you will get the desired result.
enter String BASE_URL = "https://api.test.com/";
String API_KEY = "SFSDF24242353434";
#GET("Search") //i.e https://api.test.com/Search?
Call<Products> getProducts(
#Query("one") String one,
#Query("two") String two,
#Query("key") String key
)
Result:
https://api.test.com/Search?one=Whatever&two=here&key=SFSDF24242353434
My Android app is making two GET calls to my Server API. In the first one, is this, where parameter code is a 256 char String.
$.getJSON( myServerEndpoint, {
action: "doStuff1",
username: $("#username").val(),
code: my256charString,
format: "json"
})
.done(function( data ) {
doStuff2Response(data);
});
The second one is this, where parameter code is a 5120 char String. Both reach the same server endpoint.
$.getJSON( myServerEndpoint, {
action: "doStuff2",
username: $("#username").val(),
code: my5120CharString,
format: "json"
})
.done(function( data ) {
doStuff2Response(data);
});
When I call both of them from the same device and same user connected to WiFi or most mobile data providers, it works perfectly.
However, when I connect from a Vodafone data connection, the second request never reaches the server. I cannot find any other explanation than that there is a limit on the length of the parameters with Vodafone.
Any ideas or solutions?
OK, so here it goes. First, read this: What is the maximum length of a URL in different browsers?
Yes, there's a limit in the length of the "URL", but someway I don't know how to explain why it is happening only for vodafone. Plus, I don't even know how the request pass through their servers anyways.
As for the solution, you should consider changing from GET request to POST request when the payload is too big.
Quick solution: Base64-encode the code part of the message. Downside: you must decode on the server. This is a standard function in most languages though.
If you're already using Base64 or somesuch cypher, what about Blobs? https://developer.mozilla.org/en-US/docs/Web/API/Blob
chromano's suggestion is spot-on too, just switch to POST and you will definitely get an unlimited Post Body. Downside: Have to JSON.stringify and JSON.parse for yourself, and if you want to expose this URL to a user (say as a link to share) it now can't carry the same information (URL's are GET requests).
I am new t ajax, but quite familiar with android. I am converting a ajax program to android app. As a part of it, i need to post data to the server. Below is the given post command in ajax.
var postTo = 'xyz.php';
$.post(postTo,{employee_name: $('[name=employee_name]').val() , phone: $('[name=phone]').val(), employee_type: 'guest' } ,
function(data) {
if(data.success){
window.localStorage["sa_id"] = data.mid;
window.location="getempdb.html";
}
if(data.message) {
$('#output').html(data.message);
} else {
$('#output').html('Could not connect');
}
},'json');
I want to implement this in android but under very little from the above statements. Could anyone who is good at ajax help me out with this thing. As of now, i get the user name and telephone number as a edit text input. I need to send this to php using http client. I know how to send data using php, but do not know what format to send and whether its a string to send or as a json object to send. Please help in interpreting the above code and oblige.
Apparently, this uses UrlEncodedFormEntity if you are using HttpClient in android.
This is created by using a List of NameValuePair.
from the parameters to the $.post:
{employee_name: $('[name=employee_name]').val() , phone: $('[name=phone]').val(), employee_type: 'guest' }
You have to create a NameValuePair for employee_name, one for phone ... each of which is fetched from a HTML element name employee_name, phone ... This is where you put the values from your EditTexts.
It returns a JSON formatted String, which you have to parse (typically using JSONObject obj = new JSONObject(result); once you have fetched the result from the server)
In this JSON object, you have a key named success, which format is not specified, except you can assume things went well if it is present ; a key mid, and a key message.