Json and Java. From String to JSONObject: issues - java

I'm using the library org.json.
I have a string like this (quotes can't appear in field_n)
{field1=value1, field2=value2} (say it `val`)
This string is obtained from an Hashtable<String, Object>.
I create a JSONObject from that string, obtaining:
{"field1":"value1", "field2":"value2"}
The issue arises when in the value value_n quotes (or newlines and carriage return) appear.
I've tried to escape the string in this way:
value = value.replace("\\", "\\\\");
value = value.replace("\"", "\\\"");
value = value.replace("\r", "\\r");
value = value.replace("\n", "\\n");
but I always obtain the org.json.JSONException: Expected a ',' or '}' at ... [character ... line 1] when I try to create the JSONObject with:
JSONObject json = new JSONObject(val);

In order to create JSON from map, use:
new JSONObject(myMap);
Another related issue:
quotedStr = JSONObject.quote(val.trim());
will qoute all needed values as it says:
Produce a string in double quotes with backslash sequences in all the right places

Related

Text to Json in Java (list in text)

I have the following text which is returned by an API that I call:
{"identified_faces_names": "[\"omar\", \"elhoussinep\"]"}
when I pass this text to JSONParse to parse it, it give me the following exception:
Exception in thread "main" Unexpected character (o) at position 0.
Code used to parse the text to json:
String s = new String("{\"identified_faces_names\": \" [\"omar\",\"elhoussinep\"]\"}");
JSONParser parser = new JSONParser();
Object obj = parser.parse(s);
Did you definitely mean to enclose ["omar", "elhoussinep"] in quotes? Is that definitely intended to be a String value containing string quotes? Or is it intended to be an array of strings?
If identified_faces_names is intended to be an array of strings then the valid JSON is:
{
"identified_faces_names": [
"omar",
"elhoussinep"
]
}
This is parseable, without error, like so:
String s = new String("{\"identified_faces_names\": [\"omar\",\"elhoussinep\"]}");
JSONParser parser = new JSONParser();
Object obj = parser.parse(s);
If identified_faces_names is intended to be a String containing quotes you must escape the quotes inside the string. The valid JSON is:
{
"identified_faces_names": "[\\\"omar\\\",\\\"elhoussinep\\\"]"
}
This is parseable, without error, like so:
String s = new String("{\"identified_faces_names\": \" [\\\"omar\\\",\\\"elhoussinep\\\"]\"}");
JSONParser parser = new JSONParser();
Object obj = parser.parse(s);
So, in summary, I'd suggest revisiting the JSON to determine whether it is an array of strings or a string which contains quotes, if the latter then you have to escape those quotes.
FWIW, you can use JSONLint to check whether the JSON is valid. Using this you can see that your original JSON ({"identified_faces_names": "["omar","elhoussinep"]"}) was not valid and that the first invalid character is the "o" in "omar" and that's deemed invalid because it follows "[" which is deemed to be a complete String.
Use this String {"identified_faces_names": [\"omar\", \"elhoussinep\"]}. It is correct and will parse.

CSV with tab as quote character

I have tried several CSV parsers for Java but non of them handled the following line properly:
String str = "\tvalue1\t,,\tv1,",',v3\t,value2"
The format is comma separated with TAB as escape character. Part of fields empty, part not escaped.
Any suggestion for parser which handles this format good?
For example I would expect that the above string will be parsed as:
value1
null
v1,",',v3
value2
But it's producing the following:
value1
null
v1
"
'
v3
value2
Java Example:
import java.lang.String;
import com.univocity.parsers.csv.CsvParser;
import com.univocity.parsers.csv.CsvParserSettings;
public class StamMain {
public static void main(String[] args){
String str = "\tvalue1\t,,\tv1,',",v3\t,value2";
System.out.println(str);
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setQuote('\t');
CsvParser parser = new CsvParser(settings);
String[] fields = parser.parseLine(str);
for (String f : fields)
System.out.println(f);
}
}
The best results achieved if TAB replaced by quote, but quoting quotes is interesting task by itself.
Any ideas appreciated.
Apache Commons CSV can handle it just fine.
String str = "\tvalue1\t,,\tv1,\",',v3\t,value2";
CSVFormat csvFormat = CSVFormat.DEFAULT.withQuote('\t');
for (CSVRecord record : CSVParser.parse(str, csvFormat))
for (String value : record)
System.out.println(value);
Output
value1
v1,",',v3
value2
You can even add .withNullString("") to get that null value, if you want.
value1
null
v1,",',v3
value2
Very flexible CSV parser.
Just add this line before parsing to get the result you expect:
settings.trimValues(false);
This is required because by default the parser removes white spaces around delimiters, but your "quote" character happens to be a white space. Regardless, this is something the parser should handle. I opened this bug report to have it fixed in the next version of uniVocity-parsers.
Works with Super CSV
ICsvListReader reader = new CsvListReader(
new FileReader("weird.csv"),
CsvPreference.Builder('\t', ',', "\r\n").build()
);
List<String> record = reader.read();
for(String value : record)
System.out.println(value);
Output:
value1
null
v1,",',v3
value2
One option is to:
1) Replace all the double quotes in your string with some "good" replacement string that you know won't be in the actual data (e.g. "REPLACE_QUOTES_TEMP")
2) Replace all tabs with double quotes.
3) Run the parser as normal.
4) Replace back the "REPLACE_QUOTES_TEMP" strings (or whatever you chose), in the individual fields, with the actual double quote.
The String "\tvalue1\t,,\tv1,",',v3\t,value2" is not valid. to include '"' as character you need to write '\"'.
For parsing this code should work:
String st = "\tvalue1\t,,\tv1,\",',v3\t,value2";
String[] arr = st.split("\t");

Get string from JSON like PHP in Java

I was wondering if there is a way to get a string from JSON in Java like there is in PHP:
<?php
$json = #file_get_contents('example');
$decoded_json = json_decode($json);
echo $decoded_json->{"something"} ;
?>
I have currently tried:
String input = "[{"minecraft.net":"green"},{"session.minecraft.net":"green"},{"account.mojang.com":"green"},{"auth.mojang.com":"green"},{"skins.minecraft.net":"green"},{"authserver.mojang.com":"green"},{"sessionserver.mojang.com":"green"},{"api.mojang.com":"green"},{"textures.minecraft.net":"green"}]";
String wanted = "minecraft.net";
JSONObject json = new JSONObject(input);
String out = json.getString(wanted);
System.out.println(out);
However, it gives me this error:
org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1]
Thanks!
It's because your String is not a valid JSON object but a valid JSON array which contains objects, try to use JSONArray instead then you can query around this array for your desired object
You forgot to add \" when a double quote is inside another double quote

How to escape a colon inside a datetime value in a JSON string

I need to instantiate a JSONObject with a string that I receive from an external source. The string contains a datetime value, which in turn contains a colon.
When I try to create an instance of the JSONObject, I get an error, it looks like JSON does not like the colon in the middle of the date time value.
Here is a code snippet:
#Test
public void testGetDate()
{
String jsonStr = "{\"sDate\":2013-06-15T09:30:09+0000}";
try
{
JSONObject jsonObject = new JSONObject(jsonStr);
System.out.println(jsonObject.get("sDate"));
} catch (JSONException e)
{
e.printStackTrace();
}
}
The error I get is:
org.json.JSONException: Expected a ',' or '}' at 23 [character 24 line 1]
Has anyone encountered this ? Is there some way to escape the colon?
If you surround your date/time object in double quotes, it should accept it.
This should work:
String jsonStr = "{\"sDate\":\"2013-06-15T09:30:09+0000\"}";
Strings are required to be quoted in JSON:
string
""
" chars "
Your snippet is invalid, which is why the exception is thrown. You must surround the string value with double quotes.
The more interesting issue is for cases where the string is unknown. In case the format is known then it's reasonably easy to fix. Added as a utility to org.json here.

Replace single quote with double quote with Regex

I have an app that received a malformed JSON string like this:
{'username' : 'xirby'}
I need to replaced the single quotes ' with double quoates "
With these rule (I think):
A single quote comes after a { with one or more spaces
Comes before one or more spaces and :
Comes after a : with one more spaces
Comes before one or more spaces and }
So this String {'username' : 'xirby'} or
{ 'username' : 'xirby' }
Would be transformed to:
{"username" : "xirby"}
Update:
Also a possible malformed JSON String:
{ 'message' : 'there's not much to say' }
In this example the single quote inside the message value should not be replaced.
Try this regex:
\s*\'\s*
and a call to Replace with " will do the job. Look at here.
Instead of doing this, you're better off using a JSON parser which can read such malformed JSON and "normalize" it for you. Jackson can do that:
final ObjectReader reader = new ObjectMapper()
.configure(Feature.ALLOW_SINGLE_QUOTES, true)
.reader();
final JsonNode node = reader.readTree(yourMalformedJson);
// node.toString() does the right thing
This regex will capture all appropriate single quotes and associated white spaces while ignoring single quotes inside a message. One can replace the captured characters with double quotes, while preserving the JSON format. It also generalizes to JSON strings with multiple messages (delimited by commas ,).
((?<={)\s*\'|(?<=,)\s*\'|\'\s*(?=:)|(?<=:)\s*\'|\'\s*(?=,)|\'\s*(?=}))
I know you tagged your question for java, but I'm more familiar with python. Here's an example of how you can replace the single quotes with double quotes in python:
import re
regex = re.compile('((?<={)\s*\'|(?<=,)\s*\'|\'\s*(?=:)|(?<=:)\s*\'|\'\s*(?=,)|\'\s*(?=}))')
s = "{ 'first_name' : 'Shaquille' , 'lastname' : 'O'Neal' }"
regex.sub('"', s)
> '{"first_name":"Shaquille","lastname":"O\'Neal"}'
This method looks for single quotes next to the symbols {},: using look-ahead and look-behind operations.
String test = "{'username' : 'xirby'}";
String replaced = test.replaceAll("'", "\"");
Concerning your question's tag is JAVA, I answered in JAVA.
At first import the libraries:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Then:
Pattern p = Pattern.compile("((?<=(\\{|\\[|\\,|:))\\s*')|('\\s*(?=(\\}|(\\])|(\\,|:))))");
String s = "{ 'firstName' : 'Malus' , 'lastName' : ' Ms'Malus' , marks:[ ' A+ ', 'B+']}";
String replace = "\"";
String o;
Matcher m = p.matcher(s);
o = m.replaceAll(replace);
System.out.println(o);
Output:
{"firstName":"Malus","lastName":" Ms'Malus", marks:[" A+ ","B+"]}
If you're looking to exactly satisfy all of those conditions, try this:
'{(\s)?\'(.*)\'(\s)?:(\s)?\'(.*)\'(\s)?}'
as you regex. It uses (\s)? to match one or zero whitespace characters.
I recommend you to use a JSON parser instead of REGEX.
String strJson = "{ 'username' : 'xirby' }";
strJson = new JSONObject(strJson).toString();
System.out.println(strJson);

Categories

Resources