How to write my own JSON parser? - java

I want to write a JSON parser that parses input JSON of depth n for college assignment.
As far as I have understood, I will have to convert this JSON into <String, Object> map and then create classes out of it.
Is this correct? also How would I come to know exact datatypes of the values in JSON?
for ex my sample JSON sis.
{
“name”: “user”,
“address”: {
"city":"abc",
"zip":12345
}
}
Then I am supposed to create a class named say User that has to fields
1. name: String 2. Adderss : Object
and Address class having city : string and zip :int with getters and setters.
Is this correct? How to dynamically create a class?
How should I start ?

see this for that (not recommended): Creating classes dynamically with Java.
Advice of #T.J.Crowder is a good one: some collection.
public class json_java{
Map<String,Object> values=new HashMap<String,Object>;
To get the type:
JSONObject one_object=...
Object one_value = one_object.get("city");
one_value.getClass().getName(); // => String

Related

How to convert Complex JSON string in to MAP in scala

I have a text file which contains a line like
players={"Messi":{"Details":{"Goals":500},"Country":"Argentina"},"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"], "Country":"Brazil"}}
Now I am used a regex for extract the
{"Messi":{"Details":{"Goals":500},"Country":"Argentina"},"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"],"Country":"Brazil"}}
from the text file and pass it in to a case class which accepts the value as a String.
and I am making a Dataframe using this case class.
In my case every line may be different in the contents with in the JSON String.So I am looking for a general solution to Convert any complex Json string to Map values.
When checking dataframe.printSchema, I am getting the players column as a String type.
But I need it to be as a Map type which holds a Key and value as a Struct type.
I tried method referred in this link
How can I convert a json string to a scala map?
when I used this way,I got error
"org.json4s.package$MappingException: Do not know how to convert JObject(List((Details,JObject(List((Goals,JString(500))))), (Country,JString(Argentina)))) into class java.lang.String "
and I used following solutions
Converting JSON string to a JSON object in Scala
But these too won't worked for me.
This is my case class
case class caseClass (
Players :String = ""
)
I am Extracting the json string using a user defined function.
Simply my requirement is that I have a complex Json String which contains keys and values as struct,list etc..
so I want to make the string to its corresponding JSON which holds a proper schema with respect to its contents.
Kindly expecting Valuable solutions.
If you also can live with JsValue as value instead of String it looks a bit simpler:
import play.api.libs.json._
case class CaseClass (
Players :Option[JsValue]
)
object CaseClass {
implicit val jsonFormat = Json.format[CaseClass ]
}
I saw some problems with your Json - so you would need to have something like:
val json = Json.parse("""{
"Players":{
"Messi":{"Details":{"Goals":500},"Country":"Argentina"},
"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"], "Country":"Brazil"}
}
}"""
)
To get a String out of this you can use:
json.validate[CaseClass] match {
case JsSuccess(cc, _) => cc.Players.toString
case JsError(errors) => // handle errors
}
I got another solution which I think More easier.
I Made an own schema for the JSON and Used from_json method with the schema,and it worked well.
from_json(col("Players"),ownschema).as("new_Json")
and my ownschema contains the structure of the Json String.
For any doubts, Comment.
Happy Coding.

Java, map a json

Here's what I wanna do
I have a json, like:
{
"demoNumber":123,
"demoText":"asdasdasd"
}
and I wanna make a simple String array from it, which should be
["demoNumber","demoText"]
In the app we're making the user can add any type of data, so we can't do data models for everything, that's not an option
I have added json to my Gradle:
dependencies {
implementation 'org.json:json:20180130'
}
But it still can't find the method.
Assuming you have the JSON as a string, this example uses the JSON-java library:
JSONObject jo = new JSONObject(myJsonStr);
Set<String> keys = jo.toMap().keySet();
// You should be able to extract an array from the set of keys
See also https://www.baeldung.com/java-org-json

use Scala to get JSON data in lower levels

I'm a beginner of Scala, and I have JSON data formatted like below:
{
"index_key": {
"time":"12938473",
"event_detail": {
"event_name":"click",
"location":"US"
}
}
}
I'm trying to get the content of "index_key" and extract the content of second level as a new JSON objet and initiate a class based on the second level data.
{
"time":"12938473",
"event_detail": {
"event_name":"click",
"location":"US"
}
}
I tried to use json4s to extract from the above json to be a Event class, but how to get rid of the "index_key" which is the first level key?
case class Detail(event_name: String, location: String)
case class Event(time: String, event_detail: Detail)
json.extract[Event]
I've read json4s documentation, and also http://www.scala-lang.org/api/2.10.3/index.html#scala.util.parsing.json.JSON$, but still don't quite get it, as it seems the pre-defined json should be fit for the parser?
Could anyone please tell me how to get the second level data (or any lower level) of the json structure?
You can use \ to get to the object you want to extract:
val json = parse(str) \ "index_key"
json.extract[Event]

Dynamic Creation of JSON Object Arrays

This is a continuation of my work on a gradebook program. I have been posting my questions related to JSON and connecting two applications to StackOverflow because I've been having a really difficult time with that part.
I have been attempting to create an HTTP POST request that uses JSON for the purpose of sending information from a Java gradebook application to a Rails web-based application that displays those grades in the form of a report to students.
Ultimately, I want to send more than just one student's information. Furthermore, each student might have anywhere from 0 to 50 assignments, descriptions of the assignments, as well as grades for those assignments. On top of that there will be multiple classes/courses of students. All this information needs to be "read in" to the JSON object. Does anyone have any suggestions about how I could modify this code so that I could send all that data?
The farthest that I was able to take the JSON-related part of code is shown below. However, that code needs to be modified as the following questions suggest.
1. How do I create the array of JSON objects dynamically rather than how it is shown below (since the courses, students, and grades will vary and be read in from the Java program)?
2. How do I synthesize/combine the three JSON arrays of objects below to make it work? My idea is that I write the array of course objects then somehow embed the array of student objects as part of each course object, then somehow embed the array of grade objects as part of each student object.
{‘JSONArrayOfCourseObjects’ : [{‘courseID’ : ‘Botany101FallSemester’, ‘courseInstructor’ :
‘Mr. Smith’}, {‘courseID’ : ‘Physics101FallSemester’, ‘courseInstructor’ : ‘Mrs. Newton},
etc.]}
{‘JSONArrayOfStudentObjects’ : [{‘Name’ : ‘John Doe’, ‘StudentID’ : ‘12345678’, ‘Address’ :
‘1234 Main Street’}, {‘Name’ : ‘Don Corleone’, ‘StudentID’ : ‘87654321’, ‘Address’ :
‘121 Walberry Ave’}, etc.]}
{‘JSONArrayOfGradeObjects’ : [{‘nameOfAssignment’ : ‘Irrigation Homework 1’,
‘dateOfAssignment’ : ‘Sept 1, 2014’, ‘categoryOfAssignment’ : ‘Homework’},
{‘nameOfAssignment’ : ‘Test 1’, ‘dateOfAssignment’ : ‘Sept 14, 2014’, ‘categoryOfAssignment’ :
‘Test’}, etc.]}
JSONlib is the simplest Java API out there for generating quick and dirty JSON. It has everything you need to build up the object and convert it to text. If you need something more powerful, there's GSon and Jackson.
Here are some samples. This example is in Groovy so it's not copy and pasteable, but it shows you how to use it:
def array = new JSONArray()
new File("/path/to/grades/files").eachFile { file ->
String rawJson = file.text
JSONObject obj = (JSONObject ) JSONSerializer.toJSON( rawJson )
array = array.element(obj)
})
println array.toString(5) //Use 5 character indentation

How to parse a BasicDBObject into other object

I'm developing a Java application using MongoDB and Java-driver.
I need to parse a BasicDBObject into an own object of my code, and I don't know if there is a way to develop automatically.
Is it possible to parse from BasicDBObject to JSON String? Then, I could parse from JSON String to my own Object, for example with GSON library. Something like
BasicDBObject object;
String myJSONString = object.toString();
Gson gson = new Gson();
MyOwnObject myObject = gson.fromJson(myJSONString, MyOwnObject.class);
And I don't want to add complex to my code, also I don't to add more extern libraries. I don't want to add Gson library or other.
Any ideas?? Is it possible to do this without external libraries??
Thanks!!
You could have taken a look at the API: Just call object#toString() (http://api.mongodb.org/java/2.0/com/mongodb/BasicDBObject.html#toString()).
You could either use Groovy with gmongo library for that, there you have lots of handy tools for such casting.
If the language change is not an option for you, write your own reflection-based mapper. If you POJO is simple enough, the mapper shall be pretty simple.
This is the correct answer to my question
From http://docs.mongodb.org/ecosystem/tutorial/use-java-dbobject-to-perform-saves/
For example, suppose one had a class called Tweet that they wanted to save:
public class Tweet implements DBObject {
/* ... */
}
Then you can say:
Tweet myTweet = new Tweet();
myTweet.put("user", userId);
myTweet.put("message", msg);
myTweet.put("date", new Date());
collection.insert(myTweet);
When a document is retrieved from the database, it is automatically converted to a DBObject. To convert it to an instance of your class, use DBCollection.setObjectClass():
collection.setObjectClass(Tweet.class);
Tweet myTweet = (Tweet)collection.findOne();
If for some reason you wanted to change the message you can simply take that tweet and save it back after updating the field.
Tweet myTweet = (Tweet)collection.findOne();
myTweet.put("message", newMsg);
collection.save(myTweet);

Categories

Resources