Make a dynamic URL in retrofit - java

I want url like this
baseurl/dealer/index.php?r=rest/packInfo
I am doing like this
#FormUrlEncoded
#POST("/dealer/index.php?r=rest/{method}")
void getDealersPacks(#Path("method") String method,
#Field("cd_dealer_id") String cd_dealer_id,
#Field("country_code") String country_code,
#Field("business_type")String business_type);
And i am getting error
URL query string "r=rest/{method}" must not have replace block. For dynamic query parameters use #Query.

You are passing #Path annotation for query parameter.
You can do it this way :
#FormUrlEncoded
#POST("/dealer/index.php")
void getDealersPacks( #Query("r") String query, #Field("cd_dealer_id") String cd_dealer_id, #Field("country_code") String country_code, #Field("business_type") String business_type);
Now , pass "rest/packInfo" or any other dynamic value in query parameter, it will work.
Hope , it helps !!

Related

Retrofit error URL query string must not have replace block when provide dynamically values

I want to get JSON data using retrofit get this error
Caused by: java.lang.IllegalArgumentException: URL query string
"q={text}&langpair={l_from}|{l_to}" must not have replace block. For
dynamic query parameters use #Query.
My code is
// example of my site
// http://mytempsite.com/get?q=hello friend&langpair=en|ur
#GET("get?q={text}&langpair={from}|{to}")
Call<ApiService> getJsonData(#Query("text") String text,
#Query("from") String from,
#Query("to") String to);
And my calling request
Call<ApiService> call = apiService.getJsonData("hello word","en","ur");
But when i use statically like this it will work.
#GET("get?q=Hello Word&langpair=en|ur")
Call<ApiService> getJsonData(#Query("text") String text,
#Query("from") String from,
#Query("to") String to);
try this code:
#GET(".")
Call<ApiService> getJsonData(#Query("q") String text,
#Query("langpair") String langpair);
Call<ApiService> call = apiService.getJsonData("hello word","en|ur");

Issue with Special Characters in Retrofit 2 encoding

So I'm looking to make a request to our api to log in a user, however there is a section that gets encoded in the Retrofit 2 method even though its set as encoded = true. The base url is https://testapi.test.ie The parameter I pass as the serverext is mdc.php?action= However even after setting encoded = true the resulting request body is: https://testapi.test.ie/mdc.php%3Faction=login_user&ts=1482924232742 where I require it to be: https://testapi.test.ie/mdc.php?action=login_user&ts=1482924232742 So I can see the issue is the ? symbol. Below is my retrofit method, if anyone can help with this I would appreciate it in order to achieve the correct
#retrofit2.http.POST("/{serverext}login_user&ts={timestamp}")
#retrofit2.http.Multipart
Call<LoginResponseModel> loginUser(#retrofit2.http.Path(value = "serverext", encoded = true) String server,
#retrofit2.http.Part(Constants.USER) String username,
#retrofit2.http.Part(Constants.PASS) String password,
#retrofit2.http.Path("timestamp") Long timestamp);
You use it incorrect. Path is path, Query is query. You need to rewrite your code to use this separately.
#retrofit2.http.POST("{serverext}")
#FormUrlEncoded
Call<LoginResponseModel> loginUser(#retrofit2.http.Path(value = "serverext", encoded = true) String server,
#retrofit2.http.Field(Constants.USER) String username,
#retrofit2.http.Field(Constants.PASS) String password,
#retrofit2.http.Query("timestamp") Long timestamp,
#retrofit2.http.Query("action") String action);
loginUser("mdc.php", username, pass, 42, "login_user")
You need to use #FormUrlEncoded . And you don't need to include package name in all declarations! just import them! its more neat and clean!
#POST("/{serverext}login_user&ts={timestamp}")
#Multipart
#FormUrlEncoded
Call<LoginResponseModel> loginUser(#Path(value = "server", encoded = true) String server,
#Part(SyncStateContract.Constants.USER) String username,
#Part(SyncStateContract.Constants.PASS) String password,
#Path("timestamp") Long timestamp);

RequestMapping with String parameter containing URL

I have a Spring controller with two parameter long and String:
#RequestMapping(value = "/webpage")
#Controller
public class WebpageContentController {
//...
#RequestMapping(value = "{webpageId}/{webpageAddress}", method = RequestMethod.GET)
public String contentWebpageById(#PathVariable long webpageId, #PathVariable String webpageAddress) {
System.out.println("webpageId=" + webpageId);
System.out.println("webpageAddress=" + webpageAddress);
//...
}
//...
If I invoke it like this:
http://localhost:8080/webarch/webpage/1/blahblah
All is fine:
webpageId=1
webpageAddress=blahblah
But If I pass String parameter with slash (in this case URL address):
http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
I get an error:
org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page] in DispatcherServlet with name 'appServlet'
How pass such parameter?
Well the error is caused by springs controllers mapping, when Spring sees url like
http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
It doesn't 'know' that the 'https://en.wikipedia.org/wiki/Main_Page' should be mapped as parameter to "{webpageId}/{webpageAddress}" mapping since every slash is interpreted as a deeper controler method mapping. It looks for controller method mapping like (webpage/1/http:{anotherMapping}/wiki{anotherMapping}/Main_Page{anotherMapping}) wich this kind of mapping is obviously not handled by "{webpageId}/{webpageAddress}"
EDIT
According to your comment you can try something like this
#RequestMapping(value = "/{webpageId}/**", method = RequestMethod.GET)
public String contentWebpageById(HttpServletRequest request) {
String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
String extractedPathParam = pathMatcher.extractPathWithinPattern(pattern, request.getServletPath());
extractedPathParam = extractedPathParam.replace("http:/", "http://");
extractedPathParam = extractedPathParam.replace("https:/", "https://");
//do whatever you want with parsed string..
}
Using spring 4.2.1
SomeParsing should use some Regular Expression to extract only the URL 'variable'
Just encode all special characters in the URL.
https://en.wikipedia.org/wiki/Main_Page
becomes this:
https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMain_Page
and you can pass it as URL parameter without any problems. Decoding is done automatically, so if you access the parameter as variable in your controller, it contains the URL already decoded and you can use it without any converting needed.
More information about URL encoding: https://en.wikipedia.org/wiki/Percent-encoding

Retrofit error URL query string must not have replace block

I have this function
#GET("/users?filters[0][field]={param}&filters[0][operator]=equals&filters[0][value]={value}")
UserDto retrieveUsersByFilters(#Path("param") String nameFilter, #Path("value") String value);
I try to call it like this :
UserDto currentUser = interfaceUser.retrieveUsersByFilters(User.LOGIN, login);
But i have error :
retrofit.RetrofitError: InterfaceUser.retrieveUsersByFilters: URL query string "filters[0][field]={param}&filters[0][operator]=equals&filters[0][value]={value}" must not have replace block.
I already test url on firefox and it work fine.
Thank's for your responses
Edit
Solution:
#GET("/users?filters[0][operator]=equals")
UserDto retrieveUsersByFilters(
#Query("filters[0][field]") String nameFilter,
#Query("filters[0][value]") String value);
Query params have their own annotation which automatically appends to the URL.
#GET("/users?filters[0][operator]=equals")
UserDto retrieveUsersByFilters(
#Query("filters[0][field]") String nameFilter,
#Query("filters[0][value]") String value);
You can read more about #Query on its Javadoc
URL="/api-mobile_prateek2.php?method=getProductById&pid="
#GET("/api-mobile_prateek2.php?method=getProductById")
Call<Product> responseproduct(#Query("pid") String pid);
dont put the pid in the #GET,, Retrofit automatically fix the url, using #Query
From the JavaDoc:
Example 1:
#GET("/friends")
Call<ResponseBody> friends(#Query("page") int page);
Calling with foo.friends(1) yields /friends?page=1.
Example with null:
Example 2:
#GET("/friends")
Call<ResponseBody> friends(#Query("group") String group);
Calling with foo.friends(null) yields /friends.
Array/Varargs Example:
Example 3:
#GET("/friends")
Call<ResponseBody> friends(#Query("group") String... groups);
Calling with foo.friends("coworker", "bowling") yields /friends?group=coworker&group=bowling.
Parameter names and values are URL encoded by default. Specify encoded=true to change this behavior.
Example 4:
#GET("/friends")
Call<ResponseBody> friends(#Query(value="group", encoded=true) String group);
Calling with foo.friends("foo+bar")) yields /friends?group=foo+bar.
Don't put your values directly in the path, but prefer in the method signature.
Not completely sure, but try something like this :
#GET("/users?filters[0][operator]=equals")
UserDto retrieveUsersByFilters(#Path("filters[0][field]") String nameFilter, #Path("filters[0][value]") String value);

How to read the public URL in GWT?

I m new in GWT and I m generating a web application in which i have to create a public URL.
In this public URL i have to pass hashtag(#) and some parameters.
I am finding difficulty in achieving this task.
Extracting the hashtag from the URL.
Extracting the userid from the URL.
My public URL example is :: http://www.xyz.com/#profile?userid=10003
To access the URL in GWT you can use the History.getToken() method. It will give you the entire string that follows the hashtag ("#").
In your case (http://www.xyz.com/#profile?userid=10003) it will return a string "profile?userid=10003". After you have this you can parse it however you want. You can check if it contains("?") and u can split it by "?" or you can get a substring. How you get the information from that is really up to you.
I guess you already have the URL. I'm not that good at Regex, but this should work:
String yourURL = "http://www.xyz.com/#profile?userid=10003";
String[] array = yourURL.split("[\\p{Lower}\\p{Upper}\\p{Punct}}]");
int userID = 0;
for (String string : array) {
if (!string.isEmpty()) {
userID = Integer.valueOf(string);
}
}
System.out.println(userID);
To get the parameters:
String userId = Window.Location.getParameter("userid");
To get the anchor / hash tag:
I don't think there is something, you can parse the URL: look at the methods provided by Window.Location.

Categories

Resources