Spring REST #Query variable parameters - java

I'm currently building a REST API in spring, and would like to add a search method which takes in a list of letters and search for sequences based on those letters. The code I have below is an example of what i've achieved so far. It does the job, and searches based on the letter parameters. But it's limited to have to use exactly the number of params specified in the method.
#Query("SELECT f FROM Item f " +
"WHERE LOWER(f.title) LIKE CONCAT(" +
" '%',LOWER(:letter1)," +
" '%',LOWER(:letter2)," +
" '%',LOWER(:letter3)," +
" '%',LOWER(:letter4),'%')")
#RestResource(rel = "title-fragmented", path="findByFragments")
Page<Item> findByFragmented(#Param("letter1") String letter1,
#Param("letter2") String letter2,
#Param("letter3") String letter3,
#Param("letter4") String letter4,
Pageable page
);
I was wondering if it is possible to achieve the same result without specifying the number of letters to be concatenated. So for example when
/api/v1/search/findByfragments?letter=A&letter=B&letter=C....
is called, it'll work. I've tried passing string arrays as a the #Param value, but couldn't get it to work.
Thanks in advance.

Solved my issue by using SpEL expressions to split apart a single string, and replace the letters between them with wildcard(%) expression. Example below for anyone who may find themselves with the same issue:
#Query(
"SELECT f FROM Item f WHERE LOWER(f.title) LIKE CONCAT('%',LOWER(:#{#title.replaceAll('','%')}),'%')"
)
#RestResource(rel = "item-title-by-fragments", path="fragments")
Page<Item> findUsingFragments(#Param("title") String title, Pageable page);

Related

Using delimiter in split but include the value for a specific string [duplicate]

This question already has answers here:
split string only on first instance - java
(6 answers)
Closed 1 year ago.
I have a response that I am getting from a server. The response needs to be split using the delimiter "=" but for one of the argument there is "=" in its value which needs to be included as well.
Example:
Response: Name=Hi&Code=Ind=&Age=23
Once I get this response I split the string with & as delimiter.
Next I split it with delimiter = but in this case code should have the value as Ind= but it is coming as Ind . I have other functions as well where I am using the same split function for parsing the response. Is there any regex or delimiter I can use which will be the best for my usecase here.
I tried different approach of include ahead delimiter regex but they didn't work.
I think what you want to do here is to use String#split along with its second limit parameter, which controls how many times the split is applied. In this case, we want to split on = just once.
String input = "Name=Hi&Code=Ind=&Age=23";
String[] parts = input.split("&");
for (String part : parts) {
String key = part.split("=", 2)[0];
String value = part.split("=", 2)[1];
System.out.println("Found a (key, value): (" + key + ", " + value + ")");
}
This prints:
Found a (key, value): (Name, Hi)
Found a (key, value): (Code, Ind=)
Found a (key, value): (Age, 23)

Replace a non-specific substring in a string

Well I'm trying to descover how to replace in a string like this:
String user ="123124.Ken:000"; the substring .Ken:000 with for example
.Diana:999. I think that there is something in using indexOf() of that '.' character but I don't know how to replace from that indexOf() to the end of user string.
id = user.split(".")[0] # this will have the value of 123124
new user = id + ".Diana:999"
U can write a simple function like this.
def changeUser (oldUser, user):
return oldUser.split('.')[0] + user
You can use the split function

Preventing % to %20 in replaceAll

I'm trying to format a string in a Java Servlet to add to a JDBC SELECT query. I need to replace %20's with a % for my LIKE conditional.
nameQuery.replaceAll("%20", "%");
String query = String.format("SELECT name, imageURL FROM User " +
"WHERE name LIKE \'%%%s%%\' AND userID != %d", nameQuery, userId);
With this code, all the %20 still don't get replaced. For a nameQuery value like "Allison%20s", calling nameQuery.replaceAll("%20", "%") changes it to "Allison%20s" (no change). Even escaping the % doesn't fix this. How can I make replaceAll convert the % to a %20?
It seems like what you've actually got is a string containing %20 and you want to replace it with something else. You can do that with replace
nameQuery = nameQuery.replace("%20", "%"); // replace %20 with a %
You could also have used replaceAll, but you don't appear to be capturing the return value of replaceAll; just calling it and ignoring the result.

Searching Phone number in Android Code

I am trying to implement a functionality in android app where as user keys in the numbers, I want to incrementally search those numbers in Phone book (the generic phone book search) and display result.
For this, I am using
Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(aNumber));
This seems to work for most of the cases and is handling search for ' ' etc.
There are 2 issues that I am not able to resolve :
It does not ignore the country code.
So as an e.g. if I have a number : +9199776xx123
When my search string is +9199, the result comes up. While if my search string is 9977, it does not come up.
It does not search from between.
When my search string is 776, then also result does not come up.
So the behavior of CONTENT_FILTER_URI of Phone is not exactly clear to me.
P.S. : I have tried PhoneLookup but for some reason, it does not throw any result. My belief is that it might not be capable to searching partial numbers.
After quite a lot or research, I was able to find the answer. Now, I search on both the columns, Number and normalized number. This takes care of both the cases since normalized number contains country code in the number.
My selection string looks like :
String selection = ContactsContract.CommonDataKinds.Phone.NUMBER + " LIKE ? OR "
+ ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER + " LIKE ?";
Phone.CONTENT_FILTER_URI is built for speed, but it's not perfect, as you've noticed.
You can use the plain Phone.CONTENT_URI to process any kind of request you want.
e.g.:
String partialPhone = "9977";
String[] projection = new String[] {Phone.DISPLAY_NAME, Phone.NUMBER, Phone. NORMALIZED_NUMBER};
String selection = "(" + Phone.NUMBER + " LIKE %" + partialPhone + "%) OR (" + Phone.NORMALIZED_NUMBER + " LIKE %" + partialPhone + "%)";
Cursor c = cr.query(Data.CONTENT_URI, projection, selection, null, null);

Concatenation of two strings in java with only first character in upper case

I am trying to get two string firstName and lastName which is fully in uppercase and tring to convert all the characters except the first one in lowercase and concatenate the resultant strings.
firstname="TOM";
lastName="HARRIS";
Output is : Tom Harris
I achieved it by doing:
String name =
firstName.substring(0,1).toUpperCase()
+ firstName.substring(1).toLowerCase()
+ " "
+ lastName.substring(0,1).toUpperCase()
+ lastName.substring(1).toLowerCase();
but is there any other way of doing ? a more efficient way ?
Yes, you can use the method WordUtils.capitalizeFully() from Apache Commons Lang:
String name = WordUtils.capitalizeFully(firstName + " " + lastName);
As Strings are immutable in Java, when doing that many concatenations it's more efficient to use a StringBuilder, like so:
StringBuilder s = new StringBuilder();
String name = s.append(firstName.substring(0,1).toUpperCase())
.append(firstName.substring(1).toLowerCase())
.append(" ")
.append(lastName.substring(0,1).toUpperCase())
.append(lastName.substring(1).toLowerCase()).toString();
As this only creates 2 objects: the String and the StringBuilder, rather than 4* as before.
*Concatenating a String literal is done at compile time, so adding the " " does not create a new object.
If you need a little more control in building up Strings Snippetory may help
Syntaxes.XML_ALIKE.parse("{v:x case='camelizeUpper' delimiter=' '}").append("x", firstName).append("x", lastName).toString();

Categories

Resources