Get Query Details From A URL Without Parsing It In Java - java

I am trying to receive name and value (query details) from a URL but I have a restriction that the URL shouldn't be parsed to find out query details from the URL. I tried to find the index of '?' and then add the substring on a list till index of '='-1 from the query which I found using the statement:
String query = uri.getQuery() == null || uri.getQuery().trim().isEmpty() ? "" : uri.getQuery();
The issue that comes here is I am getting an error which states:
java.net.URISyntaxException: Illegal character in query at index
Can anyone point where am I going wrong ?
The URL which I am using is:
https://xyzz.com.in/collections/two-tone-wedding-rings?ugg_9ty554_tags=ROSE|WHITE&ugg_yuiolz_price=%3A700%201000%20%7B0%7D%20-%20%7B1%7D
(The | symbol is creating issues)

I think you're using the wrong class for this
I tried doing it with URL class instead
String input = "https://xyzz.com.in/collections/two-tone-wedding-rings?ugg_9ty554_tags=ROSE|WHITE&ugg_yuiolz_price=%3A700%201000%20%7B0%7D%20-%20%7B1%7D\n"
URL uri = new URL(input);
System.out.println(uri.getQuery());
Output:
ugg_9ty554_tags=ROSE|WHITE&ugg_yuiolz_price=%3A700%201000%20%7B0%7D%20-%20%7B1%7D

Related

Why Backslash character not removed even after using replace method

I have made a rest request which is returning me a Set in JSON format which is "[\"TestBack\"]".
If I directly parse it in Apex using
Set<String> rw = (Set<String>)JSON.deserialize(response.getBody(),Set<String>.class);
then I get following error
FATAL_ERROR System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set
but if I explicitly remove double quote sign by using
Set<String> rw = (Set<String>)JSON.deserialize(response.getBody().substringAfter('"').substringBeforeLast('"'),Set<String>.class);
I got following error
FATAL_ERROR System.JSONException: Unexpected character ('\' (code 92)): expected a valid value
and if I try to use replaceAll method
Set<String> rw = (Set<String>)JSON.deserialize(response.getBody().substringAfter('"').substringBeforeLast('"').replaceAll('\\',''),Set<String>.class);
it shows following error
FATAL_ERROR System.StringException: Invalid regex: Unexpected internal error near index 1
Is there any way to get parse back into Set?

Java can't connect to MySQL if password contain % symbol

Here is my connection URL:
jdbc:mysql://mydbhost:3306/mydatabase?user=username&password=%u16*!ypK#WrUQbr
When i call
DriverManager.getConnection()
with current URL i'm catching exception:
ava.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "u1"
If connection URL not contain % everything works.
i have found some info about this issue, and there recommend to do next conversion :
replaceAll("%(?![0-9a-fA-F]{2})", "%25")
With this conversion i have error:
Access denied for user(incorrect password)
Can somebody help to convert url correctly?
Try it with below string, where all reserved characters in your password are replaced with the appropriate percent-encoded value:
% : %25
* : %2A
! : %21
# : %40
"jdbc:mysql://mydbhost:3306/mydatabase?user=username&password=%25u16%2A%21ypK%40WrUQbr"
More information about percent-encoding Wikipedia
I have tried as "Carlos Heuberger" recommended,
call getConnection(String url, String user, String password)
In this style it works, and from my view looks more clear instead of build one huge URL with all parameters included

Regular expression to check invalid input

I need to parse a a string which contains the query for the database.
The valid strings can be the following :
Status:OPEN,PENDING
Status:OPEN
Status:PENDING
Status:REJECTED
type:SMALL
type:BIG
weight>100
The following is not valid :
weight:100<PENDING
My first try was this in Java:
Pattern p = Pattern.compile("(\\w+?)(:|<|>)(\\w+)(|,)*(\\w+)*$");
Obviously, it fails to parse the last statement correctly.
I think that validating this with a regexpression is a hrad thing.
But you can try this expression:
"([\\w]+)(:(([A-Z]+)|([A-Z]+,([A-Z]+)))|(>[0-9]+))"
It worked for me in a online regexpression tester for your inputs
I created this expression for your requirement:
Pattern pattern = Pattern.compile("((Status:(OPEN|PENDING|OPEN,PENDING|REJECTED))|(type:(SMALL|BIG))|(weight[<>]\\d+))");
anything else matches invalid status, types, etc.
For example:
These are all invalid:
Status>100
type:REJECTED
weight:100
Hope this helps!

JMETER (Beanshell): Token Parsing Error: Lexical error at line 4, column 25. Encountered: "u" (117), after : "\'s"

In JMETER I have HTTP query which returns JSON String as following:
{"url":"/some/path?Id=343\u0026"}
I'm trying to parse parameter Id from it with BeanShell sampler:
url = prev.getResponseDataAsString();
int start=url.indexOf('Id=');
int end = url.indexOf('u0026')-1;
newId=url.substring(start,end);
vars.put("newId", newId);
and get an error: Token Parsing Error: Lexical error at line 4, column 25. Encountered: "u" (117), after : "\'s"
Any ideas?
So it seems like backslash confuses the parser. Tried some Java String operations (replaceAll, URLEncoder.encode) - none of them seems to help.
JSON URL contained extra parameter: {"url":"/some/path?Id=343\u0026success=1"}, so following code worked:
url = prev.getResponseDataAsString();
int start=url.indexOf("Id=")+3;
int end = url.indexOf("success=1")-6; //note: "\u0026" is 6 characters
newId=url.substring(start,end);
vars.put("newId", newId);
\u0026 is actually one character, not 6. Change line 3 to
int end = url.indexOf("\u0026");
By the way, I am not sure about your usage of single quotes. I suspect BeanShell is converting from a character array to a String in order to make it work. Best make them double quotes, just in case.

Creating a dynamic query with MongoDB, Java and Jongo

I'm using a combination of Java, the Play Framework using Java and not Scala, MongoDB and Jongo as my go between for a basic web CRUD app. I keep receiving a JSON parse exception even though my string doesn't contain any illegal characters. It's actually failing on closing curly bracket at the end of the statement. Below is my error and code. The query string is just a string builder, searching if an object is empty or has a value, if it has a value it's appended to a string.
Jongo method:
public static Iterable<OneDomain> findWithQueryString(String queryString){
return domains().find("{#}", queryString).as(OneDomain.class);
}
Controller Methods:
String builder example:
if(queryStringBuilder.toString().equalsIgnoreCase("")){
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}else{
queryStringBuilder.append(" , ");
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}
String queryString = queryStringBuilder.toString();
Iterable<OneDomain> filteredIterable = OneDomain.findWithQueryString(queryString);
Gives me this error:
Caused by: com.mongodb.util.JSONParseException:
{"source : Online Lists , blacklist : true , vetted : true , is : false , isNot : true"}
^
with the error on the "}" ending it.
In addition to that, if I try to escape the characters by putting in a \" so it becomes \"date\" it will parse and error out like so:
Caused by: com.mongodb.util.JSONParseException:
{"\"source\" : \"Online Lists\" , \"blacklist\" : true , \"vetted\" : true , \"is\" : false , \"isNot\" : true"}
Can I actually do this or because it's Java being inserted into it, the quotes will be around the whole string and thus it's trying to read it as a single JSON field vs it being the whole query?
First, make sure not to make your self vulnerable to injection attacks. Read up on injection attacks in general, and more specifically on MongoDB, eg OWASP page on Testing for NoSQL injection.
While you can indeed pass a generated query string into the find method I would not advise it. I did the same and had big problem when we generated a query containing the jongo substitution parameter #, ie
// This will throw an exception:
// java.lang.IllegalArgumentException: Not enough parameters passed to query: {"value":"#"}
...find("{" + "\"value\":\"#\"" + "}")
My solution is to pass a DBObject:
import com.mongodb.BasicDBObject
...find("#", new BasicDBObject().append("value", "#"))
It can also be built with the QueryBuilder:
import com.mongodb.QueryBuilder
...find("#", QueryBuilder.start("value").is("#").get())
It would be nice though to have query builder support directly in the Jongo API: https://github.com/bguerout/jongo/issues/173
Found the answer. Need to drop the substitution and instead my method looks like
domains().find("{"+queryString+"}").as(OneDomain.class);

Categories