How to remove backslash from exception message in SpringBoot? - java

I have this exception message:
public CityDto getCityByName(String name) throws DataNotFoundException {
CityEntity cityEntity = cityRepository.findByName(name);
if (cityEntity == null){
throw new DataNotFoundException("city with name " + '"' + name + '"' + " not found!");
}else
return CityMapper.INSTANCE.toCityDto(cityEntity);
}
and this how Postman show me this message:
{
"status": "NOT_FOUND",
"message": "Entity not found",
"errors": [
"city with name \"Toronto\" not found!"
]
}
As u can see, city name Toronto for some reason have backslash. How to remove it?

do this throw new DataNotFoundException("city with name '" + name + "' not found!")

Removing backslash is not the issue, basically you need to understand the technical details why the backslash is there.
For this you can visit this Java Strings W3Schools link to understand
as it explains
Because strings must be written within quotes, Java will misunderstand
this string, and generate an error:
String txt = "We are the so-called "Vikings" from the north.";
The solution to avoid this problem, is to use the backslash escape
character.
The backslash (\) escape character turns these characters into
string characters
The sequence \" inserts a double quote in a string

Related

How to handle Apostrophe in Strings in Java?

I have the following piece of code :
public String createDownloadLink(String user) {
String url = "No file exists";
String fileName = "download.zip";
if (userExists())
url = "<a onClick= 'downloadfile(\"" + user + "\", \"" + Encode.forJavaScript(fileName) + "\")' href='#' >Download</a>";
return url;
}
In the above piece of code, the user value is their respective email address.
This code works fine for all email addresses except for email addresses having an apostrophe in it.
Example : For user = "john.d'cruz#java.com" , the url I get in response is
<a onclick="downloadfile("john.d" cruz#java.com", "download.zip")' href="#">Download</a>
And this is a broken url so the download fails.
I tried using
user = user.replace("'","\'");
But it still gives me the same error.
How do I fix this?
If I understand correctly, you just need to escape the ' with a \, right?
If so, your method for escaping the ' sign should look like this instead.
user = user.replace("'","\\'");
Java uses \ for escaping characters, so in your method you were saying ' should be replaced with an escaped ' which basically translates back to the '. Please correct me if I understood the question incorrectly.
For escaping characters you could use:
StringEscapeUtils.escapeJava("john.d'cruz#java.com");
which results in john.d\'cruz#java.com.
Add below dependency to your project:
https://mvnrepository.com/artifact/org.apache.commons/commons-text
and this import statement:
import org.apache.commons.text.StringEscapeUtils;
Something like this should work in your case:
public String createDownloadLink(String user) {
if (userExists()) {
return String.format("<a onClick=\"downloadFile('%s', 'download.zip')\" href=\"#\" >Download</a>", StringEscapeUtils.escapeJava(user));
}
return "No file exists";
}

Regex to find if the partial input is valid JSON

I have a scenario where I need to validate whether the partial input(see below) is valid JSON or not? I have referred this answer to identify whether the given string is a valid JSON or not.
Example input:
{
"JSON": [{
"foo":"bar",
"details": {
"name":"bar",
"id":"bar",
What I have tried so far:
/ (?(DEFINE)
(?<number> -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )
(?<boolean> true | false | null )
(?<string> " ([^"\n\r\t\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " )
(?<array> \[ (?: (?&json) (?: , (?&json) )* )? \s* \]{0,1} )
(?<pair> \s* (?&string) \s* : (?&json) )
(?<object> \{ (?: (?&pair) (?: , (?&pair) )* )? \s* \}{0,1} )
(?<json> \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* )
) \A (?&json)\,{0,1} \Z /six
I made the closing of the array and objects optional(allow zero or one time). But there are some cases where this will fail, for example when you open a object without closing another object(shown below) the regex will still find a match.
Invalid, but still matches:
{
"JSON": [{
"foo":"bar",
"details": {
"name":"bar",
"id":"bar",{
How to validate the partial JSON input?
EDIT:
As mentioned by #ntahdh in the comments, this regex won't work using the java.util.regex. So now I need a regex which should work without recursion
This is not quite an answer to you question and would have been if the form of a comment if the number of characters allowed for that were adequate.
JSON is not a regular language and cannot therefore be recognized solely by a regular expression engine (if you are programming in Python, the regex package provides extensions that might make it possible to accomplish your task, but what I said is generally true).
If a parser generator is not available for your preferred language, you might consider creating a simple recursive descent parser. The regular expressions you have already defined will serve you well for creating the tokens that will be the input to that parser. Of course, you will expect that a parsing error will occur -- but it should occur on the input token being the end-of-file token. A parsing error that occurs before the end-of-file token has been scanned suggests you do not have a prefix of valid JSON. If you are working with a bottom-up, shift-reduce parser such as one generated with YACC, then this would be a shift error on something other than the end-of-file token.
why not let a parser like Gson do it for you, you basically deal with a stream and at a token level.
import java.io.IOException;
import java.io.StringReader;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
public class Main
{
public static void main(String[] args) throws Exception
{
String json = "{'id': 1001,'firstName': 'Lokesh','lastName': 'Gupta','email': null}";
JsonReader jsonReader = new JsonReader(new StringReader(json));
jsonReader.setLenient(true);
try
{
while (jsonReader.hasNext())
{
JsonToken nextToken = jsonReader.peek();
if (JsonToken.BEGIN_OBJECT.equals(nextToken)) {
jsonReader.beginObject();
} else if (JsonToken.NAME.equals(nextToken)) {
String name = jsonReader.nextName();
System.out.println("Token KEY >>>> " + name);
} else if (JsonToken.STRING.equals(nextToken)) {
String value = jsonReader.nextString();
System.out.println("Token Value >>>> " + value);
} else if (JsonToken.NUMBER.equals(nextToken)) {
long value = jsonReader.nextLong();
System.out.println("Token Value >>>> " + value);
} else if (JsonToken.NULL.equals(nextToken)) {
jsonReader.nextNull();
System.out.println("Token Value >>>> null");
} else if (JsonToken.END_OBJECT.equals(nextToken)) {
jsonReader.endObject();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
jsonReader.close();
}
}
}
source: https://howtodoinjava.com/gson/jsonreader-streaming-json-parser/
I know that using regex to validate some strings with nested structures is not easy, if not unfeasible at all.
You will probably have more chance using an existing JSON parser.
Use a stack to keep track of still opened objects and arrays.
Add required closing curly and square brackets.
Ask to the JSON parser if your new string is a valid JSON.
You will probably have to do some work to handle commas and quotes too, but you get the idea.
With a code sample:
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
String valid = "{\n" +
"\"JSON\": [{\n" +
" \"foo\":\"bar\",\n" +
" \"details\": {\n" +
" \"name\":\"bar\",\n" +
" \"id\":\"bar\"";
System.out.println("Is valid?:\n" + valid + "\n" + validate(valid));
String invalid = "{ \n" +
" \"JSON\": [{\n" +
" \"foo\":\"bar\",\n" +
" \"details\": {\n" +
" \"name\":\"bar\",\n" +
" \"id\":\"bar\",{";
System.out.println("Is valid?:\n" + invalid + "\n" + validate(invalid));
}
public static boolean validate(String input) {
Stack<String> closings = new Stack<>();
for (char ch: input.toCharArray()) {
switch(ch) {
case '{':
closings.push("}");
break;
case '[':
closings.push("]");
break;
case '}':
case ']':
closings.pop();
}
}
StringBuilder closingBuilder = new StringBuilder();
while (! closings.empty()) {
closingBuilder.append(closings.pop());
}
String fullInput = input + closingBuilder.toString();
JsonParser parser = new JsonParser();
try{
parser.parse(fullInput);
}
catch(JsonSyntaxException jse){
return false;
}
return true;
}
}
Which results in:
Is valid?:
{
"JSON": [{
"foo":"bar",
"details": {
"name":"bar",
"id":"bar"
true
Is valid?:
{
"JSON": [{
"foo":"bar",
"details": {
"name":"bar",
"id":"bar",{
false
Note that adding a comma after the "bar" line in the valid example make it invalid (because "bar",}]}} is an invalid JSON).

Java regex pattern match for []

I have a string output which I need to match and I am using a regex
String schemaName = "Amazon";
String test = "{\"data\": [], \"name\": \"Amazon\", \"title\": \"StoreDataConfig\"}";
String output= method("\\[\\]",schemaName);
Matcher n = Pattern.compile(output).matcher(test);
boolean available = n.find();
System.out.println(available);
I wanted to validate the same and passing the regex to a method as mentioned
private static String method(String data, String schemaName) throws IOException {
System.out.println(data);
return ("{\"data\": " + data + ", \"name\": " + "\"" + schemaName + "\"" + ", \"title\": \"StoreDataConfig\"}");
}
But I am always getting java.util.regex.PatternSyntaxException: Illegal repetition.
Can you let me know what is the mistake?
If I don't use a method for [] and just giving it directly, I am not getting an error
It looks like you are doing this:
Take a valid regex for matching [].
Embed the regex in some JSON
Attempt to compile the JSON-with-an-embedded-regex as if the whole lot was a valid regex.
That fails ... because the JSON-with-an-embedded-regex is not a valid regex.
For a start, the { character is a regex meta character.
But the real puzzle is .... what are you actually trying to do here?
If you simply want a regex that matches a literal string then this will do it.
Pattern p = Pattern.compile(Pattern.quote(someLiteralString)).
And you could build a regex out of sub-regexes and literal strings by using Pattern.quote to escape the literal parts and then concatenating.
If what you are ultimately trying to do here is to extract information from a JSON string using pattern matching / regexes, then ... don't. The better approach is to use a proper JSON parser, and extract the information you need from the JSON object tree.
It's because you need to escape {} characters like this "\\{"

Regex convert to convert a string to tab delimited field

I want to convert a string to get tab delimited format. In my opinion option 1 should do it. But it looks like option 2 is actually producing the desired result. Can someone explain why?
public class test {
public static void main(String[] args) {
String temp2 = "My name\" is something";
System.out.println(temp2);
System.out.println( "\"" + temp2.replaceAll("\"", "\\\"") +"\""); //option 1
System.out.println( "\"" + temp2.replaceAll("\"", "\\\\\"") +"\""); //option 2
if(temp2.contains("\"")) {
System.out.println("Identified");
}
}
}
and the output is:
My name" is something
"My name" is something"
"My name\" is something"
Identified
If you want an Excel compatible CSV format, the escaping of the double quote is two double quotes, so called self-escaping.
String twoColumns = "\"a nice text\"\t\"with a \"\"quote\"\".";
String s = "Some \"quoted\" text.";
String s2 = "\"" + s.replace("\"", "\"\"") + "\"";
And ... no head-ache counting the backslashes.
Use String#replace(CharSequence, CharSequence) instead of String#replaceAll(). The former is a simple string replacement, so it works as you'd expect if you haven't read any documentation or don't know about regular expressions. The latter interprets its arguments differently because it's a regex find-and-replace:
Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string.
You'll get this output:
My name" is something
"My name\" is something"
"My name\\" is something"
Identified

Error with Jongo parsing JSON

I'm using a combination of Java Play Framework, 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"}
You're building JSON by hand, and doing it wrong. You need to learn the basic JSON syntax requirements
A basic JSON-encoded object is
{"key1":"value1","key2":"value with \" escaped internal quote"}
Note all of the quotes. Your json string is a single very long object key with no associated value, which is not permitted. All keys must have values.

Categories

Resources