Can I use varargs in a retrofit method declaration? - java

I've got an API endpoint that is defined as:
GET https://api-server.com/something/{id_or_ids}
where ids can be a single object id or a comma separated list of ids.
e.g.
https://api-server.com/something/abcd1234
https://api-server.com/something/abcd1234,abcd4567,gdht64332
if a single id is given (and a matching object is found) I get back a json object:
{ "blah" : "blah" }
If multiple ids are given, I get the response in a json array:
[{"blah1":"bleh"}, {"blah2":"meh"}, {"blah3":"blah"}]
I'm currently thinking that I should implement this as two methods (can it be done in one?):
one that takes a single id and returns a single object:
#GET("/something/{id}")
void getObject (#Path("id") String objectId, Callback<MyObject> callback)
and
one that takes multiple ids and returns an array of objects.
#GET("/something/{ids}")
void getObject (Callback<MyObject[]> callback,#Path("ids") String ... objectIds)
Is there a way to feed the 2nd method varargs and concatenate them in the id field?
Thanks

Retrofit can't know how you want to join the strings in the path. While commas seem obvious, there's no reason why someone might want pipes (|) or colons (:) or whatever.
Because of this fact, we don't do anything and rely on you to choose.
There's two solutions to this:
Use String as the argument type and join at the call site. For example:
foo.getObject(Joiner.on(',').join(things));
Use a custom object whose toString() method deals with returning the correct format for one or many objects.

Related

Retrofit query with hashmap parameters of comma separated list java

I am trying to use the Kasses Spotify web api to get a series of recommended songs for the user. In the get request the there are two arguments a map and a call back. For the callback all good. But for the map I am not sure how to format the parameters.
This is the documentation:
#GET(value="/recommendations")
void getRecommendations(#QueryMap
Map<String,Object> options,
retrofit.Callback<Recommendations> callback)
Create a playlist-style listening experience based on seed artists, tracks and genres.
Parameters:
options - Optional parameters. For list of available parameters see endpoint documentation
callback - callback method
it says the parameters (options) are in the format Map and it points to the endpoint documentation for the parameters here:
https://developer.spotify.com/web-api/get-recommendations/
So I can see that some are optional and some are required. One example of a required one is here:
Argument:
seed_genres
Value:
A comma separated list of any genres in the set of available genre seeds.
So I am for my map in the form of:
Map <String, Object>
I am guessing String would be "seed_genres"
But for the object I am not sure how to format that:
For example if I was looking at reggae, jazz, metal.
How do I make that a comma separated list even if it is a String object I am still not sure how to format that.
Thanks in advance for your help

How to connect string with a object method?

I have the following problems: I've got 20 files, that I need to fill based on user input. I have the list of strings, which is the list fields name used in all of the 20 files. Now, what I would like to do, is to run each of those strings against each form, so that if field exist, I can fill it in, based on expression I provide.
So for example, I would have something like that (pseudo code):
for all files
for all strings in sting list
if field with name string exists, use SOME METHOD on given object
Now, as of know, I store the list of the strings in the database.
My question is: how can I assign a method (like User.getFirstName()), to each of the string in array, so that described pesudo code would run?
Thanks
The simpliest way to assign Value to Key is Map.
Map<String, Function<T,R>> mapping;

4 Key Value HashMap? Array? Best Approach?

I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.

How can I convert from java ArrayList object to real value

I'm trying to get a value from the databae.
My Database query:
String GroupID1="select idCompanies from companies where Company_Name='ACME';";
here I'm calling to a javabeans which give back an ArrayLIst with one element
ArrayList<?> IdGroup1=oper.getList(GroupID1);
then, I print the result:
System.out.println(IdGroup1);
The query works fine, however I'm getting as a result:
[javabeans.ListOneElement#609f6e68]
Instead of the real value. How can I convert the java object to the real value?
you are printing the ArrayList object IdGroup1,You need to iterate to get the alues
This code will retrieve the first (and only) item from the list:
System.out.println(IdGroup1.get(0).toString());
Adding the following will prevent a nullPointerException:
if (!IdGroup1.isEmpty())
System.out.println(IdGroup1.get(0).toString());
-Added .toString() to get the value of the object
Consider what type of Object oper.getList(GroupID1) will return.
You need to accommodate for whatever object that is and then convert it to String.
You need to:
Unpackage your list (that is a list contains, and is expected by java to possibly contain multiple objects, so it doesn't automatically 'unpack' it for you if you have a list of 1 object)
Extract your string. Here java might cleverly convert a number (int, float, etc. ) to a string for you.
For part two, look at what you expect the object to be by finding the JavaDocs for whatever package is handling your database queries. Then see how to extract your string.
It might be as simple as System.out.println(IdGroup1.get(0).toString());
Where get(0) unpackages the object from the list, and toString() extracts the string.
If you still get back javabeans.ListOneElement#41ccdc4d try other methods to extract your string....toValue() perhaps? It depends on the packages you're using.

Lists or Arrays as parameter in easytest-driven tests

this question is very easystest-specific (but i don't know a better place to ask).
Is there a way to use parameters of type Array or List? Is there probably a separator character that could be used like this (excel table):
testMethod doubleList stringList
3.5,3.4,6.7 a,b,c
(the separator char is here ',')So that i get two paramters List doublelist and List stringList.
At the moment i do this by hand: using all as String parameter and "split" them on ','. and then converting the single strings to desired type.
Is there a "easier" way with easytest?
You simply use ':' as a delimiter and EasyTest splits up the string into a collection for you.
The javadoc of the #Param annotation in EasyTest says:
"If you want to pass a Collection type, then EasyTest framework provides the functionality to instantiate the Collection class for you and pass in the right generic parameter if possible. For eg. if you have a test method like this :
#Test
public void testArrayList(#Param(name="items") ArrayList<ItemId> items){
Assert.assertNotNull(items);
for(ItemId item : items){
System.out.println("testArrayList : "+item);
}
}
then all you have to do is :
pass the list of itemIds as ":" separated list in the test data file(XML, CSV,Excel or custom), for eg: 23:56:908:666
and register an editor or converter for converting the String data to object.
In case the generic type argument to the Collection is a standard Java type(Date, Character, Timestamp, Long, Interger, Float, Double etc) then you don't have to do anything and the framework will take care of converting the String data to the requested type."
EasyTest works on row basis (as per my knowledge).
They have not given any provision for handling List of objects.
I am using the same way. I feel it easier for primitive types but what about List of Objects..?

Categories

Resources