I am setting a file path in java as follows,
String requestedFileName = param+File.separator+fileName;
request.setAttribute("requestedFileName",requestedFileName);
and i am retreving it in javascript as follows,
var selectedFileName = null;
if ('${requestScope.requestButtonParam}' == "convert") {
selectedFileName = '${requestScope.requestedFileName}';
alert("inside if: "+selectedFileName);
}
But in the alert box,i am getting file path as below
D:NewFolderAbc.html instead of D://NewFolder//Abc.html
How to get the filepath correctly in javascript?
Thanks
The trouble is most likely that your File.separator is \ which is an escape character in Javascript, so you're going to have to escape the escape character.
An easy way of doing the escaping is using Apache Commons StringEscapeUtils.escapeEcmaScript:
String requestedFileName = param+File.separator+fileName;
String escapedFileName = StringEscapeUtils.escapeEcmaScript(requestedFileName);
request.setAttribute("requestedFileName",escapedFileName);
This will change D:\NewFolder\Abc.html to D:\\NewFolder\\Abc.html which then gets correctly interpreted in your Javascript.
Related
Say I have a URL
http://example.com/query?q=
and I have a query entered by the user such as:
random word £500 bank $
I want the result to be a properly encoded URL:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
What's the best way to achieve this? I tried URLEncoder and creating URI/URL objects but none of them come out quite right.
URLEncoder is the way to go. You only need to keep in mind to encode only the individual query string parameter name and/or value, not the entire URL, for sure not the query string parameter separator character & nor the parameter name-value separator character =.
String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);
When you're still not on Java 10 or newer, then use StandardCharsets.UTF_8.toString() as charset argument, or when you're still not on Java 7 or newer, then use "UTF-8".
Note that spaces in query parameters are represented by +, not %20, which is legitimately valid. The %20 is usually to be used to represent spaces in URI itself (the part before the URI-query string separator character ?), not in query string (the part after ?).
Also note that there are three encode() methods. One without Charset as second argument and another with String as second argument which throws a checked exception. The one without Charset argument is deprecated. Never use it and always specify the Charset argument. The javadoc even explicitly recommends to use the UTF-8 encoding, as mandated by RFC3986 and W3C.
All other characters are unsafe and are first converted into one or more bytes using some encoding scheme. Then each byte is represented by the 3-character string "%xy", where xy is the two-digit hexadecimal representation of the byte. The recommended encoding scheme to use is UTF-8. However, for compatibility reasons, if an encoding is not specified, then the default encoding of the platform is used.
See also:
What every web developer must know about URL encoding
I would not use URLEncoder. Besides being incorrectly named (URLEncoder has nothing to do with URLs), inefficient (it uses a StringBuffer instead of Builder and does a couple of other things that are slow) Its also way too easy to screw it up.
Instead I would use URIBuilder or Spring's org.springframework.web.util.UriUtils.encodeQuery or Commons Apache HttpClient.
The reason being you have to escape the query parameters name (ie BalusC's answer q) differently than the parameter value.
The only downside to the above (that I found out painfully) is that URL's are not a true subset of URI's.
Sample code:
import org.apache.http.client.utils.URIBuilder;
URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();
// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24
You need to first create a URI like:
String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf"
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
Then convert that URI to an ASCII string:
urlStr = uri.toASCIIString();
Now your URL string is completely encoded. First we did simple URL encoding and then we converted it to an ASCII string to make sure no character outside US-ASCII remained in the string. This is exactly how browsers do it.
Guava 15 has now added a set of straightforward URL escapers.
The code
URL url = new URL("http://example.com/query?q=random word £500 bank $");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String correctEncodedURL = uri.toASCIIString();
System.out.println(correctEncodedURL);
Prints
http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$
What is happening here?
1. Split URL into structural parts. Use java.net.URL for it.
2. Encode each structural part properly!
3. Use IDN.toASCII(putDomainNameHere) to Punycode encode the hostname!
4. Use java.net.URI.toASCIIString() to percent-encode, NFC encoded Unicode - (better would be NFKC!). For more information, see: How to encode properly this URL
In some cases it is advisable to check if the URL is already encoded. Also replace '+' encoded spaces with '%20' encoded spaces.
Here are some examples that will also work properly
{
"in" : "http://نامهای.com/",
"out" : "http://xn--mgba3gch31f.com/"
},{
"in" : "http://www.example.com/‥/foo",
"out" : "http://www.example.com/%E2%80%A5/foo"
},{
"in" : "http://search.barnesandnoble.com/booksearch/first book.pdf",
"out" : "http://search.barnesandnoble.com/booksearch/first%20book.pdf"
}, {
"in" : "http://example.com/query?q=random word £500 bank $",
"out" : "http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$"
}
The solution passes around 100 of the test cases provided by Web Platform Tests.
Using Spring's UriComponentsBuilder:
UriComponentsBuilder
.fromUriString(url)
.build()
.encode()
.toUri()
The Apache HttpComponents library provides a neat option for building and encoding query parameters.
With HttpComponents 4.x use:
URLEncodedUtils
For HttpClient 3.x use:
EncodingUtil
Here's a method you can use in your code to convert a URL string and map of parameters to a valid encoded URL string containing the query parameters.
String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
if (parameters == null) {
return url;
}
for (Map.Entry<Object, Object> parameter : parameters.entrySet()) {
final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8");
final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8");
if (!url.contains("?")) {
url += "?" + encodedKey + "=" + encodedValue;
} else {
url += "&" + encodedKey + "=" + encodedValue;
}
}
return url;
}
In Android, I would use this code:
Uri myUI = Uri.parse("http://example.com/query").buildUpon().appendQueryParameter("q", "random word A3500 bank 24").build();
Where Uri is a android.net.Uri
In my case I just needed to pass the whole URL and encode only the value of each parameters.
I didn't find common code to do that, so (!!) so I created this small method to do the job:
public static String encodeUrl(String url) throws Exception {
if (url == null || !url.contains("?")) {
return url;
}
List<String> list = new ArrayList<>();
String rootUrl = url.split("\\?")[0] + "?";
String paramsUrl = url.replace(rootUrl, "");
List<String> paramsUrlList = Arrays.asList(paramsUrl.split("&"));
for (String param : paramsUrlList) {
if (param.contains("=")) {
String key = param.split("=")[0];
String value = param.replace(key + "=", "");
list.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
}
else {
list.add(param);
}
}
return rootUrl + StringUtils.join(list, "&");
}
public static String decodeUrl(String url) throws Exception {
return URLDecoder.decode(url, "UTF-8");
}
It uses Apache Commons' org.apache.commons.lang3.StringUtils.
Use this:
URLEncoder.encode(query, StandardCharsets.UTF_8.displayName());
or this:
URLEncoder.encode(query, "UTF-8");
You can use the following code.
String encodedUrl1 = UriUtils.encodeQuery(query, "UTF-8"); // No change
String encodedUrl2 = URLEncoder.encode(query, "UTF-8"); // Changed
String encodedUrl3 = URLEncoder.encode(query, StandardCharsets.UTF_8.displayName()); // Changed
System.out.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);
Say I have a URL
http://example.com/query?q=
and I have a query entered by the user such as:
random word £500 bank $
I want the result to be a properly encoded URL:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
What's the best way to achieve this? I tried URLEncoder and creating URI/URL objects but none of them come out quite right.
URLEncoder is the way to go. You only need to keep in mind to encode only the individual query string parameter name and/or value, not the entire URL, for sure not the query string parameter separator character & nor the parameter name-value separator character =.
String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);
When you're still not on Java 10 or newer, then use StandardCharsets.UTF_8.toString() as charset argument, or when you're still not on Java 7 or newer, then use "UTF-8".
Note that spaces in query parameters are represented by +, not %20, which is legitimately valid. The %20 is usually to be used to represent spaces in URI itself (the part before the URI-query string separator character ?), not in query string (the part after ?).
Also note that there are three encode() methods. One without Charset as second argument and another with String as second argument which throws a checked exception. The one without Charset argument is deprecated. Never use it and always specify the Charset argument. The javadoc even explicitly recommends to use the UTF-8 encoding, as mandated by RFC3986 and W3C.
All other characters are unsafe and are first converted into one or more bytes using some encoding scheme. Then each byte is represented by the 3-character string "%xy", where xy is the two-digit hexadecimal representation of the byte. The recommended encoding scheme to use is UTF-8. However, for compatibility reasons, if an encoding is not specified, then the default encoding of the platform is used.
See also:
What every web developer must know about URL encoding
I would not use URLEncoder. Besides being incorrectly named (URLEncoder has nothing to do with URLs), inefficient (it uses a StringBuffer instead of Builder and does a couple of other things that are slow) Its also way too easy to screw it up.
Instead I would use URIBuilder or Spring's org.springframework.web.util.UriUtils.encodeQuery or Commons Apache HttpClient.
The reason being you have to escape the query parameters name (ie BalusC's answer q) differently than the parameter value.
The only downside to the above (that I found out painfully) is that URL's are not a true subset of URI's.
Sample code:
import org.apache.http.client.utils.URIBuilder;
URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();
// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24
You need to first create a URI like:
String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf"
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
Then convert that URI to an ASCII string:
urlStr = uri.toASCIIString();
Now your URL string is completely encoded. First we did simple URL encoding and then we converted it to an ASCII string to make sure no character outside US-ASCII remained in the string. This is exactly how browsers do it.
Guava 15 has now added a set of straightforward URL escapers.
The code
URL url = new URL("http://example.com/query?q=random word £500 bank $");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String correctEncodedURL = uri.toASCIIString();
System.out.println(correctEncodedURL);
Prints
http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$
What is happening here?
1. Split URL into structural parts. Use java.net.URL for it.
2. Encode each structural part properly!
3. Use IDN.toASCII(putDomainNameHere) to Punycode encode the hostname!
4. Use java.net.URI.toASCIIString() to percent-encode, NFC encoded Unicode - (better would be NFKC!). For more information, see: How to encode properly this URL
In some cases it is advisable to check if the URL is already encoded. Also replace '+' encoded spaces with '%20' encoded spaces.
Here are some examples that will also work properly
{
"in" : "http://نامهای.com/",
"out" : "http://xn--mgba3gch31f.com/"
},{
"in" : "http://www.example.com/‥/foo",
"out" : "http://www.example.com/%E2%80%A5/foo"
},{
"in" : "http://search.barnesandnoble.com/booksearch/first book.pdf",
"out" : "http://search.barnesandnoble.com/booksearch/first%20book.pdf"
}, {
"in" : "http://example.com/query?q=random word £500 bank $",
"out" : "http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$"
}
The solution passes around 100 of the test cases provided by Web Platform Tests.
Using Spring's UriComponentsBuilder:
UriComponentsBuilder
.fromUriString(url)
.build()
.encode()
.toUri()
The Apache HttpComponents library provides a neat option for building and encoding query parameters.
With HttpComponents 4.x use:
URLEncodedUtils
For HttpClient 3.x use:
EncodingUtil
Here's a method you can use in your code to convert a URL string and map of parameters to a valid encoded URL string containing the query parameters.
String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
if (parameters == null) {
return url;
}
for (Map.Entry<Object, Object> parameter : parameters.entrySet()) {
final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8");
final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8");
if (!url.contains("?")) {
url += "?" + encodedKey + "=" + encodedValue;
} else {
url += "&" + encodedKey + "=" + encodedValue;
}
}
return url;
}
In Android, I would use this code:
Uri myUI = Uri.parse("http://example.com/query").buildUpon().appendQueryParameter("q", "random word A3500 bank 24").build();
Where Uri is a android.net.Uri
In my case I just needed to pass the whole URL and encode only the value of each parameters.
I didn't find common code to do that, so (!!) so I created this small method to do the job:
public static String encodeUrl(String url) throws Exception {
if (url == null || !url.contains("?")) {
return url;
}
List<String> list = new ArrayList<>();
String rootUrl = url.split("\\?")[0] + "?";
String paramsUrl = url.replace(rootUrl, "");
List<String> paramsUrlList = Arrays.asList(paramsUrl.split("&"));
for (String param : paramsUrlList) {
if (param.contains("=")) {
String key = param.split("=")[0];
String value = param.replace(key + "=", "");
list.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
}
else {
list.add(param);
}
}
return rootUrl + StringUtils.join(list, "&");
}
public static String decodeUrl(String url) throws Exception {
return URLDecoder.decode(url, "UTF-8");
}
It uses Apache Commons' org.apache.commons.lang3.StringUtils.
Use this:
URLEncoder.encode(query, StandardCharsets.UTF_8.displayName());
or this:
URLEncoder.encode(query, "UTF-8");
You can use the following code.
String encodedUrl1 = UriUtils.encodeQuery(query, "UTF-8"); // No change
String encodedUrl2 = URLEncoder.encode(query, "UTF-8"); // Changed
String encodedUrl3 = URLEncoder.encode(query, StandardCharsets.UTF_8.displayName()); // Changed
System.out.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);
I am making a javaFX project using data from files in a data directory as input. I want to use each file name as a String variable. I have already loaded the data:
File path = new File("data");
File [] files = path.listFiles();
for (int i = 0; i < files.length; i++){
if (files[i].isFile()){
items.loadData(files[i].toString());
}
The toString is now data/fileName1.csv. I want to save use fileName1 only. I have tried using the split() method in the loadData() method, like this:
fileName= fileName.split("/")[1]; //should trim to fileName1.csv, works
fileName= fileName.split("\.")[0]; //should trim to fileName1, error
The error for the second split() is "invalid escape sequence (valid ones are \b \t \n \f \r \" \' \ )".
I have tried variations to fix this. Is there a better/more efficient way to accomplish this?
Edit: Changed trim to split
You need to escape your backslash. Try \\.
But for operations like this, you should probably use Path functions such as: https://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html#getFileName()
You could use the following code and get the filename in just one line.
files[i].substring(files[i].indexOf("/") + 1);
You could do the following :
String fileName = "data/fileName1.csv";
String [] arr = fileName.split("(/|\\.)");
fileName = arr[1];
I have declared a user defined variable as 'projectHome' using below BeanShell which returns the absolute path of the jmx file.
${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer.getFileServer().getBaseDir();)}
On Windows it returns: projectHome=C:\Users\dd\Desktop\API_Testing
On MacOS it returns:
projectHome=/Users/dd/Desktop/API_Testing
The variable value is working fine in following BeanShell Sampler on MacOS:
import java.io.FileWriter;
import java.util.Arrays;
import java.io.Writer;
import java.util.List;
//Default separator
char SEPARATOR = ',';
//function write line in csv
public void writeLine(FileWriter writer, String[] params, char separator) {
boolean firstParam = true;
StringBuilder stringBuilder = new StringBuilder();
String param = "";
for (int i = 0; i < params.length; i++) {
//get param
param = params[i];
log.info(param);
//if the first param in the line, separator is not needed
if (!firstParam) {
stringBuilder.append(separator);
}
//Add param to line
stringBuilder.append(param);
firstParam = false;
}
//prepare file to next line
stringBuilder.append("\n");
//add to file the line
log.info(stringBuilder.toString());
writer.append(stringBuilder.toString());
}
//get path of csv file (creates new one if its not exists)
String csvFile = "${projectHome}/tenant_details.csv";
String[] params = {"${Email}"};
FileWriter fileWriter = new FileWriter(csvFile, true);
writeLine(fileWriter, params, SEPARATOR);
//proper close to file
fileWriter.flush();
fileWriter.close();
When I am running the script on Windows machine, it is failing because of the path having backslash.
How can I convert the backslash to forward slash within the same BeanShell Sampler so that it can work on Windows as well as MacOS?
You don't need to replace slashes / with backslashes \, slashes will work file for Windows platform as well, you can do something like:
new File("c:/Windows/system32/cmd.exe")
and it will normally resolve.
Don't refer variables like ${projectHome} and/or ${Email} in scripts, use vars shorthand instead. It stands for JMeterVariables class instance and provides read/write access to all JMeter Variables in scope. So you should be using
String csvFile = vars.get("projectHome") + "/tenant_details.csv";
and
String[] params = {vars.get("Email")};
Since JMeter 3.1 it is recommended to use JSR223 Test Elements and Groovy language for scripting so consider migrating to Groovy on next available opportunity as Beanshell (and will) become a performance bottleneck when it comes to high loads. See Apache Groovy - Why and How You Should Use It article for more information.
In beanshell Sampler/Post-PreProcessor, input the path to script folder and script name into the Script File field as:-
${__BeanShell(File.separator,)} will return the / in Unix (Mac, Linux, …) and \ in Windows. So you can consider it as:
– Windows: ${PATH}\Foldername\beanshellfile.bsh
– Unix: ${PATH}/scripts/beanshellfile.bsh
Inside Sampler you can call File.separator which uses relevant OS file separator when you need to add it. In your code change to:
String csvFile = "${projectHome}" + File.separator + "tenant_details.csv";
Here is how I solved this problem using BeanShell:
import org.apache.jmeter.services.FileServer;
String JMXPath = FileServer.getFileServer().getBaseDir();
char[]a = JMXPath.toCharArray();
log.info(JMXPath + " - It is project JMX path");
for (int i = 0; i < a.length; i++)
{
if (a[i] == '\\')
{
a[i] = '/';
}
}
String xyz = String.valueOf(a);
log.info(xyz + " - It is projectHome value");
vars.put("projectHome", xyz);
String arg="http://www.example.com/user.php?id=<URLRequest Method='GetByUID' />";
java.net.URI uri = new java.net.URI( arg );
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
desktop.browse( uri );
I want to open the given link in default browser with the above code but it says the url is invalid...i tried escaping characters like ' also but its not working.
If i replace String arg="www.google.com"; then there is no problem and I am able to open google.com.
Please help.
Your string contains characters that aren't valid in a URI, per RFC 2396. You need to properly encode the query parameters. Many utilities support that, like the standard URLEncoder (lower level), JAX-RS UriBuilder, Spring UriUtils, Apache HttpClient URLEncodedUtils and so on.
Edit: Oh, and the URI class can handle it, too, but you have to use a different constructor:
URI uri = new URI("http", "foo.com", null, "a=<some garbage>&b= |{$0m3 m0r3 garbage}| &c=imokay", null);
System.out.println(uri);
Outputs:
http://foo.com?a=%3Csome%20garbage%3E&b=%20%7C%7B$0m3%20m0r3%20garbage%7D%7C%20&c=imokay
which, while ugly, is the correct representation.
Thats because it is invalid. <URLRequest Method='GetByUID' /> should be replaced by the value of the id, or an expression that returns the id which you can concatenate with the arg string. Something like
String arg="http://www.example.com/user.php?id="+getByUID(someUid);
import java.net.URL;
import java.net.URLEncoder;
class ARealURL {
public static void main(String[] args) throws Exception {
String s1 = "http://www.example.com/user.php?id=";
String param = "<URLRequest Method='GetByUID' />";
String encodedParam = URLEncoder.encode(param,"UTF-8");
URL url = new URL(s1+encodedParam);
System.out.println(url);
}
}
Output
http://www.example.com/user.php?id=%3CURLRequest+Method%3D%27GetByUID%27+%2F%3E