Using a Map<String, String[]> as #RequestParam in Spring with csv notation - spring

Since one of my endpoints is getting more and more parameters i would like to convert noting down every parameter on its own into using a map. The parameters themselves consist of a two element array of values.
As an example:
Call: getstuff?param1=value1,gt&param2=value2,eq
Current Method: getStuff(#RequestParam String[] param1, #RequestParam String[] param2)
What i want: getStuff(#RequestParam Map<String, String[]> params)
If i do this, the String[] will only ever contain one String, and not be split on the comma into two values.
How can i achieve that it works the same as with the explicit parameters, preferrably without parsing things myself?

Related

How to make Gson read value as String?

My JSON objects look like this
{"phoneNbr":"123456789","firstName":"Mark","previousNames":[{"previous1":"Peter","previous2":"Steve"}]}
{"phoneNbr":"234567891","firstName":"Hank","previousNames":null}
The previousNames values can be anything. I want it to be treated a STRING always. However when I try to parse it, GSON complaints because it expects array.
PersonJsonDAO class looks like this
private String phoneNbr;
private String firstName;
private String previousNames;
I try to parse it but GSON says Expected a string but was BEGIN_ARRAY
PersonJsonDAO personJsonDAO= new Gson().fromJson(jsonString, PersonJsonDAO.class);
How can I force GSON to accept previousNames as String?
GSON is treating it as an array, because it is indeed an array :)
I can think of 4 different alternatives to meet your desired behavior:
A preprocessing step of turning everything after '"previousNames":' into a string, by searching for the first occurance of '"previousNames":[', inserting there a '"', backspacing all the double quotes, till the occurrence of ']', before which I would add another double quote.
a much easier solution, if you don't mind the slight computational overhead, which in your case is probably tiny, just parse into a JSON as a first step, like you did, but declaring previousNames as an array of Strings, and then calling:
personJsonDAO.getString("previousNames");
However, this will leave you with previousNames field as an array of Strings.
Another option is to leave it as a JSonObject in the deserilization process, like this:
class PersonJsonDAO {
....
#SerializedName("previousNames")
JsonObject previousNames;
....
}
If the above alternatives are not enough, and you insist on having the previousNames field as a String, then the most comprehensive and correct approach would be to override the desiarilzation process of GSON, calling super for all behaviours, except when meeting the previousNames culprit, which you would return as a String.

Is including parameter in params redundant, when also using #RequestPram?

In a example like:
#GetMapping(value = "/artists", params = "genre")
public List<Artist> getArtists(#RequestParam String genre) {
}
is including genre in the params redundant since it is also declared using #RequestParam in the method signature ?
When trying to map to different methods for the same URL, is the method signature the one that metters, or is also defining params necessary?
In the #RequestMapping annotation (and other HTTP method specific variants), the params element is meant for narrowing the request mappings based on query parameter conditions. From the documentation:
The parameters of the mapped request, narrowing the primary mapping.
Same format for any environment: a sequence of myParam=myValue style expressions, with a request only mapped if each such parameter is found to have the given value. Expressions can be negated by using the != operator, as in myParam!=myValue. myParam style expressions are also supported, with such parameters having to be present in the request (allowed to have any value). Finally, !myParam style expressions indicate that the specified parameter is not supposed to be present in the request.
In the other hand, the #RequestParam annotation allows you to bind a query parameter to a method argument.
Refer to the documentation for details.

Spring Batch Passing list of values as a parameter

I want to pass list of id's as one of parameter to Spring batch. Is this possible to achieve?
Thanks in advance.
What you are trying to do is not possible.
From the JobParameter doc:
Domain representation of a parameter to a batch job. Only the
following types can be parameters: String, Long, Date, and Double. The
identifying flag is used to indicate if the parameter is to be used as
part of the identification of a job instance.
You might be tempted write your list of of id's to a comma delimited string and pass that as a single parameter but beware that when stored in the DB it has a length of at most 250 bytes. You'll either have to increase that limit or use another way.
Perhaps you can explain what why you need to pass that list of ids.
If you want to pass the list from ItemReader, then you have to get JobParameters first (you have to declare your reader to be step scoped for that, see this thread also).
You will have to put your list as a parameter to the JobParameters. As JobParameters is immutable, you will have to create a new object then
List yourList = ....
JobParameters jp = (JobParameters) fac.getBean("params");
Map map=params.getParameters();
map.put("yourList", list);
params=new JobParameters(map);
launcher.run(job, params);
You cannot use the List<T> concept itself in spring-batch, but I think you can implement your intentions(listOf(a, b, c, d..)) in the following way.
The job parameter itself receives a comma-separated string of items.
#Nonnull
private List<String> someList = Collections.emptyList();
#Value("#{jobParameters['someList']}")
public void setTableNames(#Nullable final String someList) {
if (StringUtils.isNotBlank(tableNames)) {
this.someList = Arrays.stream(StringUtils.split(someList, ","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
}
}
Hope it was helpful for using list-type parameters in spring-batch!
Thanks.

OpenNLP Name Entity Recognizer output

I have trained an OpenNLP Name Entity Recognizer. When I use it over some data it gives an output like:
[0..1) location
I rather want to output the original name that occurred in the data.
this is a Span objects toString() output. Each call to find(String[]) can return multiple Spans, hence the find() method returns Span[].
Use this code to get the actual named entities
//"tokens" here is the String[] of words in your sentence
Span[] find = nf.find(tokens);
//use the Span's static method to get the String[] of names
String[] namedEntities = Span.spansToStrings(find, tokens);
A span is simply a start and end index to your String[] tokens.

Map Support in Shell Scripting

I am new in Shell Scripting, however i am friendly with Java Maps. I Just wanted to know that how can i use Map facility in Shell Scripting. Below is the facility i need to use in shell-
HashMap<String, ArrayList<String>> users = new HashMap<String, ArrayList<String>>();
String username = "test_user1";
String address = "test_user1_address";
String emailId = "test_user1_emailId";
ArrayList<String> values = new ArrayList<String>();
values.add(address);
values.add(emailId);
users.put(username, values);
String anotherUser = "test_user2";
if (users.containsKey(anotherUser)) {
System.out.println("Do some stuff here");
}
In short, i want to use a Map, which has String as key, either Vector or ArrayList as value (otherwise i have live with Arrays instead of ArrayList and manually take care of indexes) , put method to insert and one more method to check the presence of the key in the existing Map.
The above code is a sample code.
Thank you in advance.
bash does not support nested structures like this. Either use separate variables for each array, or use something more capable such as Python.

Resources