I have the following endpoint:
#GetMapping(path = "/{folder}/**")
public void myEndpoint(#PathVariable("folder") String folder,
HttpServletRequest request) {
//...
}
I want to extract the ** as String. The ** can look as follows - /path/to/obj.
I've came up with the following solution:
request.getRequestUri().substring(folder + '/');
However, the SonarQube yells that building the reqular expression should be avoided with tainted, user-controlled data.
refactor this code to not construct the regular expression from tainted user-controlled data
Is there a better, more secure way, to write this extraction?
How about using another #PathVariable?
#GetMapping(path = "/{folder}/{suffix}")
public void myEndpoint(
#PathVariable("folder") String folder,
#PathVariable("suffix") String suffix,
HttpServletRequest request)
{
// ...
}
This is applicable when there are no more slashes (/) present in the request URL.
Otherwise, I am not aware of any other solution. You might want to parse the captured request and validate using java.net.URL.
I came out with the following solution:
int position = request.getRequestUri().lastIndexOf(folder) + folder.length() + 1);
String myPath = request.getRequestUri().substring(position);
I'm calculating the index where my subpath starts. To do that, I'm taking the last index of the root path. It returns me the starting index of the folder String. Then I have to add the length of the String and increase by 1 (stands for slash).
Related
output = output.replaceAll("%(\\w+)%",getVar("$1"));
public String getVar(name){...return formatted;}
I have this line of code (In JAVA), and a function called getVar() that will give me the value of the variable with the name we want. The function is working perfectly, but this code doesn't seem to look for the groups anymore.
The String I am formatting with this regex is:
"My name is %name% and I am %age% years old."
And instead of giving me back: "My name is Paulo and I am 15 years old." (Because name = Paulo and age = 15) It gives me nothing back. Instead of replacing the regex with getVar(name) or getVar(age), it replaces it with getVar("$1").
Is there some way of fixing it, is this a bug, or intended behaviour? And if it is, how can I get the same result another way?
EDIT:
for(String i: varnames){
output = output.replaceAll("%"+i+"%",getVar(i));
}
Does the job for this specific case... But yet, is there a way to use functions inside of replaceAll() and maintaining the groups (e.g. $1, $2) working inside the function?
EDIT 2:
//Variables//
ArrayList<String> varnames = new ArrayList<String>(0);
ArrayList<String> varvalues = new ArrayList<String>(0);
//end of Variables
private String getVar(String name){
String returnv = "";
if(varnames.contains(name.toLowerCase())) returnv = varvalues.get(varnames.indexOf(name.toLowerCase()));
//System.out.println("\n\n"+name+"\n\n");
return returnv;
}
private String format(String input){
String output = input;
output = output.replace("[br]","/n");
for(String i: varnames){
output = output.replaceAll("%"+i+"%",getVar(i));//This is how I am parsing the variables.
}
//Here I want to handle inline functions... for example: a function called 'invert' that would switch the letters. If the input String that is being formatted (output) contains the regex, the function needs to evaluate and replace.
//How I tried to do it:
output.replaceAll("invert\((\w+)\)",invertLetters("$1"));
return output;
}
public String invertLetters(String input){//Inverts the letters of the String}
As mentioned by codisfy it is not clear at all if you are talking about java or javascript, as you use the replaceAll method I will consider that you use java. However what I will explain hereunder is valid for most (if not all) regex engines independently about the programming language.
When you call outputString=inputString.replaceAll("REGEX","REPLACEMENT"); the method replaceAll will configure its internal regex engine, build a finite automaton (for simplicity let's omit the difference between DFA/NFA here) with the regex passed as parameter and analyse the inputString on which it is called in order to do the replacement and return the result (outputString).
When the method is called it also needs a replacement String (REPLACEMENT) that is a normal string which may contain or not back-references to some groups, in order to enable some contextual replacement (using the syntax $1, $2 or \1, \2,... depending on the language).
What is very important to understand is that the regex as well as its replacement string are both just simple strings with no special meaning outside the regex engine (the method replaceAll).
Therefore, if you reuse them in other methods (for example by passing them as parameters) they will be interpreted literally as it is the case with other normal strings.
So do not expect that $1 is replaced by name or age in your call getVar("$1"). It will be just $1 and nothing else.
Also, this being said, your method public void getVar(name){...} does not even return a string since its return type is void, as consequence, if you code in java and if you use replaceAll method of String class (which expects 2 strings as arguments) it will NOT even compile in the first place.
I will let you implement the rest of the code but if you change your replacement loop in the following way it should work:
String input="My name is %name% and I am %age% years old.";
Matcher matcher = Pattern.compile("%(\\w+)%").matcher(input);
String output=new String(input);
while (matcher.find()) {
System.out.println("------------------------------------");
System.out.println("Back reference:" + matcher.group(1));
String group=matcher.group(1);//give access to the first matching group so that it can be reused
output=output.replaceAll("%"+group+"%", getVar(group));
}
System.out.println(output);
getVar method code: (I will let you adapt it)
public static String getVar(String name){
if(name.equals("name"))
return "Paulo";
return "15";
}
OUTPUT:
------------------------------------
Back reference:name
------------------------------------
Back reference:age
My name is Paulo and I am 15 years old.
Hello I have a url string like
http://example.com/foo/?bar=15&oof=myp
Now lets say that I want to change the int value in the bar parameter to 16, in order to have
http://example.com/foo/?bar=16&oof=myp
How can I do this? Considering that the number after the = might be of 1, 2 or ever 3 characters. Thank you
You can use UriComponentsBuilder (it's part of Spring Web jar) like this:
String url = "http://example.com/foo/?bar=15&oof=myp";
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromUriString(url);
urlBuilder.replaceQueryParam("bar", 107);
String result = urlBuilder.build().toUriString();
Substitute 107 with the number you want. With this method you can have URI or String object from urlBuilder.
Use regex to find the number parameter in the string url
Use String.replace() to replace the old parameter with the new parameter
I wish to purge the http:// and www. parts of an URL String using one statement.
I am not after wizardly regex-solutions, I simply want to know if there is a way to replace (read: remove) both words in one single replace statement.
Dream scenario:
String url = "http://www.superfect.com";
String[] purge = {"http://", "www."};
url = url.replace(purge, "");
This does not run, however. How is this usually done in Java?
In a single line, with a single replacement action:
url = url.replaceAll("http://|www\\.", "");
Do this in a simple loop:
String purge[] = {"www.", "http://", "https://", "ftp://"};
String result = url;
for (int i = 0; i < purge.length; ++i)
{
result = result.replace(purge[i], "");
}
Now, the result String is the one you want. As codesalsa pointed out and given the context of URL's, you might want to do it this way:
String purge[] = {"http://", "https://", "ftp://", "www."}; //order is important!
String result = url;
for (int i = 0; i < purge.length; ++i)
{
if (result.startsWith(purge[i])
{
result = result.substring(purge[i].length);
}
}
Java doesn't offer a method for replacing more than one literal character sequence at a time. Regular expressions could be used, to match both intended replacement targets in the same call.
Without regular expressions, you need to call replace once for each target.
url = url.replace("http://", "").replace("www.", "");
You could do
url = url.replaceAll("http://(?:www\\.)?", "");
You've got already plenty of nice & working solutions written right here. I'm, however, kinda a fan of clean, easily-understandable code. There's nothing more wonderful than elegant one-command solution. Here you go. You're welcome!
public class Test {
public static String parseDomainName(String url) {
return (
url.startsWith("http://www.") ? url.replaceFirst("http://www\\.", "") :
url.startsWith("http://") ? url.replaceFirst("http://", "") :
url.startsWith("www.") ? url.replaceFirst("www\\.", "") :
url
);
}
public static void main(String[] args) {
System.out.println(parseDomainName("http://www.google.com"));
System.out.println(parseDomainName("http://google.com"));
System.out.println(parseDomainName("www.google.com"));
System.out.println(parseDomainName("google.com"));
System.out.println(parseDomainName("http://misleading.www.com"));
}
}
Alright, I'm just joking! But it's the single solution right here, which works in one command and doesn't use regular expressions (well, method replaceFirst() actually accepts only a regular expressions, but it'd be working on the same logic even with different method, which accepts only plain text string).
Use this solution as it's the best compromise if you really want to avoid using regular expressions. This solution I've made is really just a joke and it'd be horrible to see it used somewhere. :-)
How about this?
url = url.replace("http://www.", "");
Wouldn't that work?
I need to substract an specific parameter (urlReturn) from a URL like this :
http://somedomain.mx/th=6048000&campus=A&matric=L01425785&serv=GRAD&count=2&per=TEST&passwd=69786e720c0f0e&mount=1000.00&urlReturn=http://somedomain.mx:7003/SP/app/login.xhtml?id=1234&mat=2323&fh=05012014124755&store=TESO
My final string should look like this:
String urlReturn = http://somedomain.mx:7003/SP/app/login.xhtml?id=1234&mat=2323;
And the rest of the string should look like this:
String urlReturn2 = http://somedomain.mx/th=6048000&campus=A&matric=L01425785&serv=GRAD&count=2&per=TEST&passwd=69786e720c0f0e&mount=1000.00&fh=05012014124755&store=TESO
I currently have this :
String string = string.toString().split("\\&")[0];
But the urlReturn parameter should always come as the first one.
Try this (s is your original String):
urlReturn = s.substring(0, s.indexOf("&urlReturn=")).replace("&urlReturn=", "");
urlReturn2 = s.substring(s.indexOf("&urlReturn=")).replace("&urlReturn=", "");
Definitely not elegant at all, but working. I really need some sleep now so take my anser carefully :) You may alswo wanto to check if the parameters is in the String s via the contains method to avoid index out of bounds exceptions.
use string#split
url.split("\\?")[1];
My problem is when I get a string from the REST service and set it as a string in java. It looks like this
<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">returnedValue</string>
How should I go about extracting the returnedValue from this?
Your string is just an XML fragment (or document by itself) so to get the value you will need to parse it. You can do so by many different means but for this specific case maybe the best option is to use something like:
String str = // Your string from the REST service
int start = str.indexOf("\">");
int end = str.indexOf("</string>", start);
String returnedValue = str.substring(start + "\">".length(), end);
Other options would be to use a regular expression or an XML parser.