I have a method that can return QRcode data in {'p':1,"x":10,"y":20} this format and it is captured in a variable called qrdata (which is a String data type ).
My question is how can I retrieve value from that key , value pair object ?if .... String qrdata = readQR(image) then how can I retrieve data from qrdata ?
You can use the JSONObject class from javax.json as mentioned in BuildSlayer's answer.
In the example in your question you use simple quotes for 'p'. Assuming it is not a typo and you meant that different charcacters can be used as quotes, you could run into trouble using it though. In that case, you could use plain java to parse your qrData String:
public String[] parseJSON(String qrData){
String[] output = new String[qrData.length()];
int i = 0;
for (String keyValuePair:qrData.split(",")) {
output[i++] = keyValuePair.split(":")[1];
}
return output;
}
}
You can do the following:
JSONObject jsonObject = new JSONObject(qrData);
System.out.println("p: " + jsonObject.getInt("p"));
System.out.println("x: " + jsonObject.getInt("x"));
System.out.println("y: " + jsonObject.getInt("y"));
Output:
p: 1
x: 10
y: 20
Related
I am currently working on migrating a database from a non-SQL source to an SQL database. The non-SQL source outputs the data in a JSON doc that is just a series of independent JSON objects. I an using JSONObject within Java, and that (to my understanding) can only recognize the top most object within the document. In order to get around this issue I am writing code to convert the independent objects into an array.
The current method I am using involves converting the JSON doc into a string, counting curly brackets to find objects, and then inserting them into an array.
for (int i = 0; i < doc.length(); i++) {
char currentChar = doc.charAt(i);
if (currentChar == '{') {
Integer jsonStart = i;
Integer openBrace = 1;
Integer closeBrace = 0;
while (openBrace > closeBrace) {
i++;
currentChar = doc.charAt(i);
if (currentChar == '{') {
openBrace++;
}
if (currentChar == '}') {
closeBrace++;
}
}
Integer jsonEnd = i;
String currentString = doc.substring(jsonStart, jsonEnd + 1);
JSONObject currentJSONObject = new JSONObject(currentString);
returnJSONArray.put(currentJSONObject);
Due to size, the database had to be divided into multiple 10k object documents. The code worked well until one of the documents had braces stored within the value. So I added some code to watch for values and ignore those based on quotation marks beneath the close curly bracket counter.
if (currentChar == '"') {
i++;
currentChar = mongoExport.charAt(i);
while (!(currentChar == '"')) {
i++;
currentChar = mongoExport.charAt(i);
}
This worked for the document with value pairs that contained curly brackets, but upon testing it against the rest of the documents I experience a "String index out of range: big number" error in one of the other documents that traces back to the while loop looking for and end quotation mark. From what I can figure, this means that there are also values that contain quotation marks. I tried some code to check for escape characters before quotation marks, but that changed nothing. I can't check through these documents manually, they are far too long for that. Is there a way for me to handle these strings? Also, was there a far easier method I could have used that I was unaware of from the beginning?
Even using the java.json package doesn't require manual parsing. something like:
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
...
private static final String jsonString = "[" +
"{\n" +
"\"id\":123,\n" +
"\"name\":\"Bob Marley\",\n" +
"\"address\":{\n" +
"\"street\":\"123 Main St\",\n" +
"\"city\":\"Anytown\",\n" +
"\"state\":\"CO\",\n" +
"\"zipcode\":80205\n" +
"},\n" +
"\"phoneNumbers\":[\"3032920200\"],\n" +
"\"role\":\"Developer\"\n" +
"},\n" +
"{\n" +
"\"id\":456,\n" +
"\"name\":\"Tommy Tutone\",\n" +
"\"address\":{\n" +
"\"street\":\"456 Main St\",\n" +
"\"city\":\"Sometown\",\n" +
"\"state\":\"CO\",\n" +
"\"zipcode\":80205\n" +
"},\n" +
"\"phoneNumbers\":[\"1238675309\"],\n" +
"\"role\":\"Developer\"\n" +
"}\n" +
"]";
...
#GET
#Produces("text/plain")
public String hello() {
InputStream inputStream = new ByteArrayInputStream(jsonString.getBytes());
JsonReader jsonReader = Json.createReader(inputStream);
JsonArray jsonArray = jsonReader.readArray();
for (JsonValue jsonValue : jsonArray) {
JsonObject jsonObject = jsonValue.asJsonObject();
System.out.println("next object id is " + jsonObject.getInt("id"));
JsonObject addressObject = jsonObject.getJsonObject("address");
System.out.println("next object city is " + addressObject.getString("city"));
}
return "Hello, World!";
}
This gets the first level objects (for example, "id") and nested objects ("address" in this example). I intentionally did not create a POJO type object that would represent the JSON object - you can do that but you'll have to decide if it's worthwhile to have a full object of your data or just pull it with things like getString().
I'm working on developping a webservice that communicate two application with each other, the first application will send a json object to the second one.
I'm stuck in translating this json object :
$body = "{"fields":{"project":{"key":"'+$projectKey+'"}
,"issuetype":{"name": "'+$issueType+'"}
,"summary":"'+$summary+'"
,"description":"'+$description+'"
,"customfield_12721":"'+$FirstName+'"
,"customfield_12722":"'+$LastName+'"
,"customfield_12723":{"value":"'+$EmployeeCategory+'"}
,"customfield_12732":"'+$Externalfunction+'"
,"customfield_12725":"'+$CorporateID+'"
,"customfield_12726":{"value":"'+$VermegCompany+'"}
,"customfield_12685":{"value":"'+$IndusRegion+'"}
,"customfield_12673":{"value":"'+$Product+'"}
,"customfield_12727":{"value":"'+$Profile+'"}
,"customfield_12667":{"name":"'+$Manager+'"}
,"customfield_12708":"'+$BeginDate+'"
,"customfield_14000":"'+$Reglementation+'"
,"customfield_14001":"'+$Department+'"
,"customfield_14002":"'+$SubDepartment+'"}
}";
To a String variable like :
String json = "{fields:{project:{\"key\":\""+ projectkey +"}"
+ "\",\"issuetype\":\""
+ "\",\"customfield_12721\":\"" + employee.getFirstName()
+ "\",\"description\":\"" + description
+ "\",\"summary\":\"" + summary
+ "\",\"customfield_12722\":\""+ employee.getLastName()
+ "\",\"customfield_12732\":\"" + employee.getFte()
+ "\",\"customfield_14000\":\"" + employee.getReglementation()
+ "\",\"customfield_14001\":\"" + employee.getDepartment()
+ "\",\"customfield_14002\":\"" + employee.getSubdepartment()
+ "\",\"fulltime\":" + Math.round(Double.parseDouble(employee.getFulltime().replaceAll(",",".")))
//+ ",\"email\":\"" + employee.getEmail()
+ ",\"citizenship\":\"" + employee.getCitizenship()
+ "\",\"gnn\":\""+ employee.getGnn()
+ "\",\"company\":\"" + employee.getCompany()
+ "\",\"employeeid\":\"" + employee.getEmployeeid()
+ "\",\"customfield_12708\":\"" + employee.getStartdate()
//+ "\",\"enddate\":\"" //+ employee.getEnddate()
+ "\",\"product\":\"" + employee.getProduct()
+ "\",\"customfield_12725\":\"" + employee.getInternalnumber()
// + "\",\"employeeid\":\"" + employee.getEmployeeid()
+ "\"}}";
Can you please help ?
Here you can use JsonConvert library to get json data.bellow are the example how to use it
String json = "{\"FirstName\":\"Jack\",\"LastName\":\"Tor\"}";
var data = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
Console.WriteLine(data);
Console.ReadLine();
Using a web tool
If you just want to convert it fast into a string, you can use a Json to String converter on the web.
Using a library
If you however want a good solution in you applications, a way to solve this problem would be to serialize and parse using a library such as GSON. This is of course, if you don't intend to create this conversion yourself.
GSON is quite easy to use and takes care of the translation for you. Se example below:
The sending application:
Gson gson = new Gson();
String jsonStr = gson.toJson(employee); // Serialize (from Java class to JSON string)
// Send data (jsonStr) ...
The receiving application:
// Receive data (jsonStr) ...
Gson gson = new Gson();
Employee employee = gson.fromJson(jsonStr); // Parse (from JSON string to Java class)
GSON will by default name the fields the same as the member variable names in the Java class. If you need to change the field names in the JSON string, you can use #SerializedName("newName") in front of the member variables.
Example:
class Employee {
...
#SerializedName("customfield_12721") String firstName;
...
}
One of my webservice return below Java string:
[
{
id=5d93532e77490b00013d8862,
app=null,
manufacturer=pearsonEducation,
bookUid=bookIsbn,
model=2019,
firmware=[1.0],
bookName=devotional,
accountLinking=mandatory
}
]
I have the equivalent Java object for the above string. I would like to typecast or convert the above java string into Java Object.
I couldn't type-cast it since it's a String, not an object. So, I was trying to convert the Java string to JSON string then I can write that string into Java object but no luck getting invalid character "=" exception.
Can you change the web service to return JSON?
That's not possible. They are not changing their contracts. It would be super easy if they returned JSON.
The format your web-service returns has it's own name HOCON. (You can read more about it here)
You do not need your custom parser. Do not try to reinvent the wheel.
Use an existing one instead.
Add this maven dependency to your project:
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.0</version>
</dependency>
Then parse the response as follows:
Config config = ConfigFactory.parseString(text);
String id = config.getString("id");
Long model = config.getLong("model");
There is also an option to parse the whole string into a POJO:
MyResponsePojo response = ConfigBeanFactory.create(config, MyResponsePojo.class);
Unfortunately this parser does not allow null values. So you'll need to handle exceptions of type com.typesafe.config.ConfigException.Null.
Another option is to convert the HOCON string into JSON:
String hoconString = "...";
String jsonString = ConfigFactory.parseString(hoconString)
.root()
.render(ConfigRenderOptions.concise());
Then you can use any JSON-to-POJO mapper.
Well, this is definitely not the best answer to be given here, but it is possible, at least…
Manipulate the String in small steps like this in order to get a Map<String, String> which can be processed. See this example, it's very basic:
public static void main(String[] args) {
String data = "[\r\n"
+ " {\r\n"
+ " id=5d93532e77490b00013d8862, \r\n"
+ " app=null,\r\n"
+ " manufacturer=pearsonEducation, \r\n"
+ " bookUid=bookIsbn, \r\n"
+ " model=2019,\r\n"
+ " firmware=[1.0], \r\n"
+ " bookName=devotional, \r\n"
+ " accountLinking=mandatory\r\n"
+ " }\r\n"
+ "]";
// manipulate the String in order to have
String[] splitData = data
// no leading and trailing [ ] - cut the first and last char
.substring(1, data.length() - 1)
// no linebreaks
.replace("\n", "")
// no windows linebreaks
.replace("\r", "")
// no opening curly brackets
.replace("{", "")
// and no closing curly brackets.
.replace("}", "")
// Then split it by comma
.split(",");
// create a map to store the keys and values
Map<String, String> dataMap = new HashMap<>();
// iterate the key-value pairs connected with '='
for (String s : splitData) {
// split them by the equality symbol
String[] keyVal = s.trim().split("=");
// then take the key
String key = keyVal[0];
// and the value
String val = keyVal[1];
// and store them in the map ——> could be done directly, of course
dataMap.put(key, val);
}
// print the map content
dataMap.forEach((key, value) -> System.out.println(key + " ——> " + value));
}
Please note that I just copied your example String which may have caused the line breaks and I think it is not smart to just replace() all square brackets because the value firmware seems to include those as content.
In my opinion, we split the parse process in two step.
Format the output data to JSON.
Parse text by JSON utils.
In this demo code, i choose regex as format method, and fastjson as JSON tool. you can choose jackson or gson. Furthermore, I remove the [ ], you can put it back, then parse it into array.
import com.alibaba.fastjson.JSON;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SerializedObject {
private String id;
private String app;
static Pattern compile = Pattern.compile("([a-zA-Z0-9.]+)");
public static void main(String[] args) {
String str =
" {\n" +
" id=5d93532e77490b00013d8862, \n" +
" app=null,\n" +
" manufacturer=pearsonEducation, \n" +
" bookUid=bookIsbn, \n" +
" model=2019,\n" +
" firmware=[1.0], \n" +
" bookName=devotional, \n" +
" accountLinking=mandatory\n" +
" }\n";
String s1 = str.replaceAll("=", ":");
StringBuffer sb = new StringBuffer();
Matcher matcher = compile.matcher(s1);
while (matcher.find()) {
matcher.appendReplacement(sb, "\"" + matcher.group(1) + "\"");
}
matcher.appendTail(sb);
System.out.println(sb.toString());
SerializedObject serializedObject = JSON.parseObject(sb.toString(), SerializedObject.class);
System.out.println(serializedObject);
}
}
I have a Json string like below
String jsonRequestString = "{\"access_code\" : \"9bPbN3\" , "
+ "\"merchant_reference\" : \"123\", \"language\" : \"en\",\"id\" : \"149018273\","
+ "\"merchant_identifier\" : \"gKc\", \"signature\" : \"570fd712af47995468550bec2655d9e23cdb451d\", "
+ "\"command\" : \"VOID\"}";
I have a String variable as
String code = "9bPbN3";
Question, how do I plugin the above string instead of hardcoding it at the below place. i.e. instead of 9bPbN3, I want to use the variable code there.
String jsonRequestString = "{\"access_code\" : \"9bPbN3\" , "
Many Thanks in advance.
If you are struggling to arrange the "'s the correct syntax would be
String jsonRequestString = "{\"access_code\" : \""+code+"\" , ";
Instead of formatting Json string manually, which takes alot of effort, consider using a library or util.
For ex (going to use Jackson library) :
Request re = new Request();
re.setCode(code);
...
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(re);
String yourVariable = "xyz";
String jsonRequestString = "{\"access_code\" : \"" + yourVariable + "\" , "
+ "\"merchant_reference\" : \"123\", \"language\" : \"en\",\"id\" : \"149018273\","
+ "\"merchant_identifier\" : \"gKc\", \"signature\" : \"570fd712af47995468550bec2655d9e23cdb451d\", "
+ "\"command\" : \"VOID\"}";
General advice is to avoid crafting a json structure out of vanilla strings. Instead use a json parser/writer library for this operations.
Checkout http://stleary.github.io/JSON-java/index.html / http://stleary.github.io/JSON-java/index.html .
There a various other libraries and tutorials available.
If you don't want to go this direction, use a "known value" placeholder and substitute it. So the full json would contain "access_code" : "##ACCESS_CODE##" and you would Substitute the placeholder with the real value. So your json string would be some kind of a string template.
Another option would be to use the format method like so:
String jsonRequestString = "{\"access_code\" : \"%s\" , "
+ "\"merchant_reference\" : \"123\", \"language\" : \"en\",\"id\" : \"149018273\","
+ "\"merchant_identifier\" : \"gKc\", \"signature\" : \"570fd712af47995468550bec2655d9e23cdb451d\", "
+ "\"command\" : \"VOID\"}";
String code = "9bPbN3";
String result = String.format(jsonRequestString, code);
Notice the "%s" I put in the place of where code would go. When you call the format method with code as a parameter, it puts it where the "%s" was.
I´m parsing a plain text and trying to convert into an Object.
The text looks like(and i can´t change the format):
"N001";"2014-08-12-07.11.37.352000";" ";"some#email.com ";4847 ;"street";"NAME SURNAME ";26 ;"CALIFORNIA ";21
and The Object to convert:
String index;
String timestamp;
String mail;
Integer zipCode
...
I´ve tried with:
StringTokenizer st1 = new StringTokenizer(N001\";\"2014-08-12-07.11.37.352000\";\" \";\"some#email.com \";4847 ;\"street\";\"NAME SURNAME \";26 ;\"CALIFORNIA \";21);
while(st2.hasMoreTokens()) {
System.out.println(st2.nextToken(";").replaceAll("\"",""));
}
And the output is the correct one, i´ve thinking to have a counter and hardcoding with a case bucle and set the field deppending the counter, but the problem is that I have 40 fields...
Some idea?
Thanks a lot!
String line = "N001";"2014-08-12-07.11.37.352000";" ";"some#email.com ";4847 ;"street";"NAME SURNAME ";26 ;"CALIFORNIA ";21
StringTokenizer st1 = new StringTokenizer(line, ";");
while(st2.hasMoreTokens()) {
System.out.println(st2.nextToken().replaceAll("\"",""));
}
Or you can use split method and directly get a array of values using the delimiter ;
String []values = line.split(";");
then iterate through the array and get and cast the values they way you want
Regardless of the way you are parsing the file, you somehow need to define the mapping of column-to-field (and how to parse the text).
if this is a CVS file, you could use a library like super-csv. All you need to do is write a mapping definition.
I would first split your input String based on the semi-colon separator, then clean up the values.
For instance:
String input = "\"N001\";\"2014-08-12-07.11.37.352000\";\" " +
"\";\"some#email.com " +
"\";4847 ;\"street\";\"NAME " +
"SURNAME \";26 ;\"CALIFORNIA " +
"\";21 ";
// raw split
String[] split = input.split(";");
System.out.printf("Raw: %n%s%n", Arrays.toString(split));
// cleaning up whitespace and double quotes
ArrayList<String> cleanValues = new ArrayList<String>();
for (String s: split) {
String clean = s.replaceAll("[\\s\"]", "");
if (!clean.isEmpty()) {
cleanValues.add(clean);
}
}
System.out.printf("Clean: %n%s%n", cleanValues);
Output
Raw:
["N001", "2014-08-12-07.11.37.352000", " ", "some#email.com ", 4847 , "street", "NAME SURNAME ", 26 , "CALIFORNIA ", 21 ]
Clean:
[N001, 2014-08-12-07.11.37.352000, some#email.com, 4847, street, NAMESURNAME, 26, CALIFORNIA, 21]
Note
In order to map the values to your variables you will need to know their index in advance, and it will have to be consistent.
Then you can use the get(int i) method to retrieve them from your List - e.g. cleanValues.get(2) will get you the e-mail, etc.
Note (2)
If you do not know the indices in advance or they may vary, then you are in trouble.
You can of course try to get those indices by using regular expressions but I suspect you might end up complicating your life quite a bit.
you can use Java Reflection to automate your process.
Iterate over the fields
Field[] fields = dummyRow.getClass().getFields();
and set your values
SomeClass object = construct.newInstance();
field.set(object , value);