Retrofit path encode except character? - java

I use retrofit and my interface below
#GET("{link}")
fun search(#Path(value = "link", encoded = true) link: String?): Call<Any>
Do I need to use encoded for all link except character '?'.
Example:
Link -> /api/search?&query=تست
Encoded link by retrofit -> api/search%3F&query=%D8%AA%D8%B3%D8%AA
I need this link-> api/search?&query=%D8%AA%D8%B3%D8%AA
I need don't convert character '?' to %3F.
do is anyway?

#Url should be used for this instead of #Path
#GET
Call<ResponseClass> list(#Url String url);
It works fine with full URL and a path that is used then with base URL.
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://website.com/");
.build();
MyService service = retrofit.create(MyService.class);
service.exampleCall("https://another-website.com/example");
service.anotherExampleCall("/only/path/part");

Don't use Path ,you can use #Query in your method,it won't convert ? to %3F .
You can change your method to
#GET("api/serach")
fun search(#Query("query") value: String?): Call<Any>
For example,your value is "aolphn",this code will access
http(s)://xxx/api/search?query=aolphn
? will appended automatically.

I find a solution, must use Interceptor for the request.
class RemoveCharacterInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val path = request.url().toString()
val string = path.replace("%3F", "?") // replace
val newRequest = request.newBuilder()
.url(string)
.build()
return chain.proceed(newRequest)
}
}
and add to httpClient
val httpClient = OkHttpClient.Builder()
httpClient.addInterceptor(RemoveCharacterInterceptor())

Related

Problems Sending FormUrlEncoded using Retrofit

I have this request and I need to send it by FormUrlEncoded using Retrofit
{
"clnt_id": "OQW",
"clnt_res": "AA!##$T",
"type": "SCDS",
"len": "ASD"
}
I used this code:
#FormUrlEncoded
#POST("Endpoint")
#Headers("Accept: Application/JSON")
fun connect(
#Field("clnt_id") clnt_id: String,
#Field(value = "clnt_res", encoded = false) clnt_res: String,
#Field("type") type: String,
#Field("len") len: String
): Observable<Token>
First, thing is that the request is not sent as JSON
Second, the value of "clnt_res", encoded by retrofit
You have 2 options to send json request from android using Retrofit.
Create Pojo Model of json request and pass it by setting values of it.
Create HashMap and pass it to request.
Here is solution using 2nd Method:
Create hashmap and put key(parameters) and value:
Map<String,String> requestMap = new HashMap<>();
requestMap.put("clnt_id","your_value");
requestMap.put("clnt_res","your_value");
requestMap.put("type","your_value");
requestMap.put("len","your_value");
Then pass it to your retrofit request using FieldMap:
#FormUrlEncoded
#POST("Endpoint")
#Headers("Accept: Application/JSON")
fun connect(
#FieldMap requestMap:Map<String,String>
): Observable<Token>
I finally get the answer and it was a problem with symbol '$' in 'clnt_res' value "AA!##$T", The problem is in kotlin to escape a special char you need to do this "\$", what I made the IDE didn't tell me that it is wrong is this "$/".

How to pass object in the header with post man post request?

I'm using postman and trying to pass an object in the header but getting an error for the converting from string to object... how would I do it right?
I'm attaching pictures from postman:
https://imgur.com/a/5wAxIYf
this is the code on the server:
#RequestMapping(
path= arrayOf(
"/wristbands/upload",
"/wristbands/upload/"),
method = arrayOf(RequestMethod.POST),
consumes = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
open fun wristbandProcessNewAlgorithem(#RequestHeader(name = "X-V", required = true) wristbandRecords: WristbandRecordNewInputDTO): ResponseEntity<*>{
var res=wristbandProcessingService.processWristbandNewAlgorithem(wristbandRecords)
return ResponseEntity(res,HttpStatus.OK)
}
What am I doing wrong?
Thank you
Solution:
I think I found solution and it was moving the object from the header to the body and changing the code to be like this:
#RequestMapping(
path= arrayOf(
"/wristbands/upload",
"/wristbands/upload/"),
method = arrayOf(RequestMethod.POST),
headers = arrayOf("X-V"),
consumes = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
open fun wristbandProcessNewAlgorithem(#RequestBody wristbandRecords: WristbandRecordNewInputDTO): ResponseEntity<*>{
var res=wristbandProcessingService.processWristbandNewAlgorithem(wristbandRecords)
return ResponseEntity(res,HttpStatus.OK)
}

Android Retrofit read response if key not string

I have a retrofit response like this:
langs: {
af: "Afrikaans",
am: "Amharic",
ar: "Arabic",
az: "Azerbaijani",
ba: "Bashkir",
...
I tried to read it to List<Map<String,String>>but it not works.
Have anyone idea what is the best way to convert this json to object?
Call:
val result = RestAPI.instance.retrofit?.create(TranslateService::class.java)
val call = result?.getLangs("en")
call?.enqueue(object : Callback<LangsResponse>{
override fun onFailure(call: Call<LangsResponse>?, t: Throwable?) {
}
override fun onResponse(call: Call<LangsResponse>?, response: Response<LangsResponse>?) {
}
})
data class LangsResponse(val dirs: List<String>,val langs: List<Map<String,String>>)
langs is a JSON object, so it can be read as a Map<String,String>. If it was an array of objects ([{..},{..}]) it would be List<Map<String,String>>.
Simply adjust the type and it should read properly.

How to deal with dot in an url path in writing service

I am writing a "GET" endpoint looks like following:
#RequestMapping(value = "/{configSetId}/{version}", method = RequestMethod.GET, produces = { "application/json" })
public ResponseEntity<List<Metadata>> getMetadatasByConfigSetIdAndVersion(
#PathVariable("configSetId") final String configSetId,
#PathVariable("version") final String version) {
return ResponseEntity.ok(metadataService.getMetadatasByConfigSetIdAndVersion(configSetId, version));
}
So I can send a "GET" request to localhost:8080/{configSetId}/{version}, for example: localhost:8080/configSet1/v1
But the problem is if the version is "v1.02", then the ".02" will be ignored and the version I got is v1. How can I avoid this behaivor? Thank you!
Since "." is special character so don't use it directly on your request.
Instead of
v1.02
Just try
v1%2E02
Where %2E is URL encoding of ".".
For more information, please refer to this link HTML URL Encoding

java.lang.IllegalArgumentException: baseUrl must end in / while using retrofit 2.1.0 for GET method

I am using Retrofit2 for API parsing.
While using retrofit1.9.0 both post and get methods work properly. But using retrofit 2.1.0, in the get method, there is an error:
java.lang.IllegalArgumentException: baseUrl must end in /
I have checked my code and there is no problem, it's working for the post method.
Retrofit retrofit= new Retrofit.Builder()
.baseUrl("sample.com/ecomtest/index.php?route=api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
'?' can not in baseUrl, you should move it to API interface. like this.
The full url :https://free-api.heweather.com/v5/now?
city=yourcity&key=yourkey
so, baseUrl = "https://free-api.heweather.com/v5/"
and the API interface
#GET("now?")
Observable<HeWeather5> getNowWeather(#Query("city") String city,#Query("key") String key);
The URL you have passed as API_BASE_URL should end with "/" so add it at the end of your URL.
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
where
String API_BASE_URL = "http://www.domain.com/"; //string end with "/"
it will work.
In retrofit you can not use endpoints like "some?" in base URL.
Split you URL like
String url="http://sample.com/ecomtest/index.php?route=api/";
String baseUrl=url.split(".com/")[0]+".com/";
String queryUrl=url.split(".com")[1];
then use
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create());
and pass you end point as a path to request method like
#GET("{endpoint}")
Call<Response> getData(#Path("endpoint") String endpoint);
and done
Suppose your url is "https://yourapi.com/abc?def&key=123"
Split your url into two parts.
String baseURL ="https://yourapi.com/"; //make sure you have '/' at the end
String key = "123";
then add rest in the GET annotation like this #GET("abc?def&key="+key)
Had the same situation and answers here almost cover/explain the solution.
However not exactly.
I tried to store BASE_URL like this: sample.com/api
And my endpoints would be for e.x: /users
The solution with adding / didn't help: sample.com/api/
The problem is with more than one / in the BASE_URL and I guess retrofit gets crazy about that the slash is not only as the ending mark.
The only solution that worked: sample.com/
And the endpoint for that would be: api/users
So keeping just one / in the BASE_URL was the solution for me, and keep it at the end of the base url string
sure to set [encoded = false] Like This :
suspend fun getAnyThing(#Query("api_key", encoded = false) apikey: String)
I solved this Error by using URL = "URL/". There has to be / as the last character to make it work.

Categories

Resources