What is the alternative of Jackson in python? - java

I am using Jackson parser for parsing for Java object to JSON. I am forcefully adding JSON keys for some java objects, using the following code.
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
#JsonSubTypes({ #JsonSubTypes.Type(value = A.class, name = "a"),
#JsonSubTypes.Type(value = F.class, name = "f") })
I am having same set classes in Python also. I would like to do the same thing in python. But not sure about what are the alternatives for this Jackson annotation available in python.
My requirement is that I have to send a POST request to a REST API. I need to serialize the java object into JSON. But as my class structure is a little bit different I don't have all the JSON keys mentioned handy in java classes. To solve the issue what I am doing is that I am adding 'a' key in JSON when it finds 'A' object is passed from java. It is doing the same thing for 'F' object. So, I have achieved the solution the way I mentioned above. I want to achieve the same thing in Python.
Is there some JSON parser available what does the same thing as mentioned above, or I have to follow some different approach for that?

I would strongly recommend the pydantic library, which also provides the possibility to add validations of the data.
It is very easy and straightforward to use, also if you only use it for json marshalling/unmarshalling.
https://pypi.org/project/pydantic/
import json
from datetime import datetime
from pydantic import BaseModel
class MyInnerClass(BaseModel):
timestamp: datetime
some_string: str
class MyOuterClass(BaseModel):
inner_instance: MyInnerClass
other_string: str
# Class to json
test_class = MyOuterClass(inner_instance=MyInnerClass(timestamp=datetime(2022, 6, 22), some_string="some"),
other_string="other")
json_string = test_class.json()
# Json to Class
input_string = '{"inner_instance": {"timestamp": "2022-06-22T00:00:00", "some_string": "some"}, "other_string": "other"}'
loaded_class = MyOuterClass(**json.loads(input_string))

attrs + cattrs is very close for the task.
copy one cattr example here,
>>> import attr, cattr
>>>
>>> #attr.s(slots=True, frozen=True) # It works with normal classes too.
... class C:
... a = attr.ib()
... b = attr.ib()
...
>>> instance = C(1, 'a')
>>> cattr.unstructure(instance)
{'a': 1, 'b': 'a'}
>>> cattr.structure({'a': 1, 'b': 'a'}, C)
C(a=1, b='a')
but it's not as capable as Jackson, i've not yet been able to find a solution to map attribute between serialized json and deserialized python object.

I have the same problem and could not find anything suitable.
So I wrote pyson
https://tracinsy.ewi.tudelft.nl/pubtrac/Utilities/wiki/pyson
It's still under development and I will add new features along the way.
It's not ment to be a complete substitute for jackson as jackson is huge. I just implement what I need, in jackson style where possible.

I think the most similar option you will get in python ecosystem will be jsonpickle
although it's not as complete as complete Jackson.
python engineers and users chose a different respectable perspective and that is using schema-less approaches to problems so typing oriented serialization libraries like Jackson doesn't have a strong equivalent in Python.

You can use Jsonic library.
Jsonic is a lightweight utility for serializing/deserializing python objects to/from JSON.
Jsonic allows serializing/deserializing to/from specific Class instances.
It supports many of the functionalities Jackson supports in Java.
Example:
from jsonic import serialize, deserialize
class User(Serializable):
def __init__(self, user_id: str, birth_time: datetime):
super().__init__()
self.user_id = user_id
self.birth_time = birth_time
user = User('id1', datetime(2020,10,11))
obj = serialize(user) # {'user_id': 'id1', 'birth_time': {'datetime': '2020-10-11 00:00:00', '_serialized_type': 'datetime'}, '_serialized_type': 'User'}
# Here the magic happens
new_user : User = deserialize(obj) # new_user is a new instance of user with same attributes
Jsonic has some nifty features:
You can serialize objects of types that are not extending Serializable. 2. This can come handy when you need to serialize objects of third party library classes.
Support for custom serializers and deserializers
Serializing into JSON string or python dict
Transient class attributes
Supports both serialization of private fields or leave them out of the serialization process.
Here you can find some more advanced example:
from jsonic import Serializable, register_jsonic_type, serialize, deserialize
class UserCredentials:
"""
Represents class from some other module, which does not extend Serializable
We can register it using register_serializable_type function
"""
def __init__(self, token: str, exp: datetime):
self.token = token
self.expiration_time = exp
self.calculatedAttr = random.uniform(0, 1)
# Register UserCredentials which represents class from another module that does not implement Serializable
# exp __init__ parameter is mapped to expiration_time instace attribute
register_jsonic_type(UserCredentials, init_parameters_mapping={'exp': 'expiration_time'})
class User(Serializable):
transient_attributes = ['user_calculated_attr'] # user_calculated_attr won't be serialized and deserialzied
init_parameters_mapping = {'id': 'user_id'} # id __init__ parameter is mapped to user_id instace attribute
def __init__(self, user_id: str, birth_time: datetime, user_credentials: UserCredentials, *args):
super().__init__()
self.user_id = user_id
self.birth_time = birth_time
self.user_credentials = user_credentials
self.user_calculated_attr = 'user_calculated_attr'
user = User(user_id='user_1', birth_time=datetime(1995, 7, 5, 0),
user_credentials=UserCredentials(token='token', exp=datetime(2020, 11, 1, 0)))
# Here the magic happens
user_json_obj = serialize(user, string_output=True)
new_user = deserialize(user_json_obj, string_input=True, expected_type=User)
Full disclosure: I'm the creator of Jsonic, i recommend you read the Jsonic GitHub repository README to see if it fits your needs.

Related

Parse a .ttl file and map it to a Java class

I am new to OWL 2, and I want to parse a ".ttl" file with OWL API, but I found that OWL API is not same as the API I used before. It seems that I should write a "visitor" if I want to get the content within a OWLAxiom or OWLEntity, and so on. I have read some tutorials, but I didn't get the proper way to do it. Also, I found the tutorials searched were use older version of owl api. So I want a detailed example to parse a instance, and store the content to a Java class.
I have made some attempts, my codes are as follows, but I don't know to go on.
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
File file = new File("./source.ttl");
OWLOntology localAcademic = manager.loadOntologyFromOntologyDocument(file);
Stream<OWLNamedIndividual> namedIndividualStream = localAcademic.individualsInSignature();
Iterator<OWLNamedIndividual> iterator = namedIndividualStream.iterator();
while (iterator.hasNext()) {
OWLNamedIndividual namedIndividual = iterator.next();
}
Instance for example are as follows. Specially, I want store the "#en" in the object of "ecrm:P3_has_note".
<http://data.doremus.org/performance/4db95574-8497-3f30-ad1e-f6f65ed6c896>
a mus:M42_Performed_Expression_Creation ;
ecrm:P3_has_note "Créée par Teodoro Anzellotti, son commanditaire, en novembre 1995 à Rotterdam"#en ;
ecrm:P4_has_time-span <http://data.doremus.org/performance/4db95574-8497-3f30-ad1e-f6f65ed6c896/time> ;
ecrm:P9_consists_of [ a mus:M28_Individual_Performance ;
ecrm:P14_carried_out_by "Teodoro Anzellotti"
] ;
ecrm:P9_consists_of [ a mus:M28_Individual_Performance ;
ecrm:P14_carried_out_by "à Rotterdam"
] ;
efrbroo:R17_created <http://data.doremus.org/expression/2fdd40f3-f67c-30a0-bb03-f27e69b9f07f> ;
efrbroo:R19_created_a_realisation_of
<http://data.doremus.org/work/907de583-5247-346a-9c19-e184823c9fd6> ;
efrbroo:R25_performed <http://data.doremus.org/expression/b4bb1588-dd83-3915-ab55-b8b70b0131b5> .
The contents I want are as follows:
class Instance{
String subject;
Map<String, Set<Object>> predicateToObject = new HashMap<String,Set<Object>>();
}
class Object{
String value;
String type;
String language = null;
}
The version of owlapi I am using is 5.1.0. I download the jar and the doc from there. I just want to know how to get the content I need in the java class.
If there are some tutorials that describe the way to do it, please tell me.
Thanks a lot.
Update: I have known how to do it, when I finish it, I will write an answer, I hope it can help latecomers of OWLAPI.
Thanks again.
What you need, once you have the individual, is to retrieve the data property assertion axioms and collect the literals asserted for each property.
So, in the for loop in your code:
// Let's rename your Object class to Literal so we don't get confused with java.lang.Object
Instance instance = new Instance();
localAcademic.dataPropertyAssertionAxioms()
.forEach(ax -> instance.predicateToObject.put(
ax.getProperty().getIRI().toString(),
Collections.singleton(new Literal(ax.getObject))));
This code assumes properties only appear once - if your properties appear multiple times, you'll have to check whether a set already exists for the property and just add to it instead of replacing the value in the map. I left that out to simplify the example.
A visitor is not necessary for this scenario, because you already know what axiom type you're interested in and what methods to call on it. It could have been written as an OWLAxiomVisitor implementing only visit(OWLDataPropertyAssertionAxiom) but in this case there would be little advantage in doing so.

Using ScalaCheck to generate an object without constructor parameters

For my Java application I am trying to use ScalaCheck to write some property-based unit tests. For that purpose I need generators, but all the tutorials I can find use a constructor with parameters to generate objects.
The object I need to generate does not have constructor parameters, and I cannot add such a constructor since it is from an external library.
I now have the following (JwtClaims is from the package org.jose4j.jwt):
def genClaims: Gen[JwtClaims] = {
val url = arbString
val username = arbString
val claims = new JwtClaims()
claims.setNotBeforeMinutesInThePast(0)
claims.setExpirationTimeMinutesInTheFuture(60)
claims.setSubject(username) // error about Gen[String] not matching type String
claims
}
Any suggestions on how to write my generator? I have zero knowledge of Scala, so please be patient if I've made an 'obvious' mistake :) My expertise is in Java, and testing using ScalaCheck is my first venture into Scala.
You need to be returning a generator of a claims object, not a claims object. The generator is effectively a function that can return a claims object. The normal way I go about this is with a for comprehension (other people prefer flatMap, but I think this reads more clearly).
def genClaims: Gen[JwtClaims] = {
for {
url <- arbitrary[String]
username <- arbitrary[String]
} yield {
val claims = new JwtClaims()
claims.setNotBeforeMinutesInThePast(0)
claims.setExpirationTimeMinutesInTheFuture(60)
claims.setSubject(username)
claims
}
}

Scala/Play: parse JSON into Map instead of JsObject

On Play Framework's homepage they claim that "JSON is a first class citizen". I have yet to see the proof of that.
In my project I'm dealing with some pretty complex JSON structures. This is just a very simple example:
{
"key1": {
"subkey1": {
"k1": "value1"
"k2": [
"val1",
"val2"
"val3"
]
}
}
"key2": [
{
"j1": "v1",
"j2": "v2"
},
{
"j1": "x1",
"j2": "x2"
}
]
}
Now I understand that Play is using Jackson for parsing JSON. I use Jackson in my Java projects and I would do something simple like this:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> obj = mapper.readValue(jsonString, Map.class);
This would nicely parse my JSON into Map object which is what I want - Map of string and object pairs and would allow me easily to cast array to ArrayList.
The same example in Scala/Play would look like this:
val obj: JsValue = Json.parse(jsonString)
This instead gives me a proprietary JsObject type which is not really what I'm after.
My question is: can I parse JSON string in Scala/Play to Map instead of JsObject just as easily as I would do it in Java?
Side question: is there a reason why JsObject is used instead of Map in Scala/Play?
My stack: Play Framework 2.2.1 / Scala 2.10.3 / Java 8 64bit / Ubuntu 13.10 64bit
UPDATE: I can see that Travis' answer is upvoted, so I guess it makes sense to everybody, but I still fail to see how that can be applied to solve my problem. Say we have this example (jsonString):
[
{
"key1": "v1",
"key2": "v2"
},
{
"key1": "x1",
"key2": "x2"
}
]
Well, according to all the directions, I now should put in all that boilerplate that I otherwise don't understand the purpose of:
case class MyJson(key1: String, key2: String)
implicit val MyJsonReads = Json.reads[MyJson]
val result = Json.parse(jsonString).as[List[MyJson]]
Looks good to go, huh? But wait a minute, there comes another element into the array which totally ruins this approach:
[
{
"key1": "v1",
"key2": "v2"
},
{
"key1": "x1",
"key2": "x2"
},
{
"key1": "y1",
"key2": {
"subkey1": "subval1",
"subkey2": "subval2"
}
}
]
The third element no longer matches my defined case class - I'm at square one again. I am able to use such and much more complicated JSON structures in Java everyday, does Scala suggest that I should simplify my JSONs in order to fit it's "type safe" policy? Correct me if I'm wrong, but I though that language should serve the data, not the other way around?
UPDATE2: Solution is to use Jackson module for scala (example in my answer).
Scala in general discourages the use of downcasting, and Play Json is idiomatic in this respect. Downcasting is a problem because it makes it impossible for the compiler to help you track the possibility of invalid input or other errors. Once you've got a value of type Map[String, Any], you're on your own—the compiler is unable to help you keep track of what those Any values might be.
You have a couple of alternatives. The first is to use the path operators to navigate to a particular point in the tree where you know the type:
scala> val json = Json.parse(jsonString)
json: play.api.libs.json.JsValue = {"key1": ...
scala> val k1Value = (json \ "key1" \ "subkey1" \ "k1").validate[String]
k1Value: play.api.libs.json.JsResult[String] = JsSuccess(value1,)
This is similar to something like the following:
val json: Map[String, Any] = ???
val k1Value = json("key1")
.asInstanceOf[Map[String, Any]]("subkey1")
.asInstanceOf[Map[String, String]]("k1")
But the former approach has the advantage of failing in ways that are easier to reason about. Instead of a potentially difficult-to-interpret ClassCastException exception, we'd just get a nice JsError value.
Note that we can validate at a point higher in the tree if we know what kind of structure we expect:
scala> println((json \ "key2").validate[List[Map[String, String]]])
JsSuccess(List(Map(j1 -> v1, j2 -> v2), Map(j1 -> x1, j2 -> x2)),)
Both of these Play examples are built on the concept of type classes—and in particular on instances of the Read type class provided by Play. You can also provide your own type class instances for types that you've defined yourself. This would allow you to do something like the following:
val myObj = json.validate[MyObj].getOrElse(someDefaultValue)
val something = myObj.key1.subkey1.k2(2)
Or whatever. The Play documentation (linked above) provides a good introduction to how to go about this, and you can always ask follow-up questions here if you run into problems.
To address the update in your question, it's possible to change your model to accommodate the different possibilities for key2, and then define your own Reads instance:
case class MyJson(key1: String, key2: Either[String, Map[String, String]])
implicit val MyJsonReads: Reads[MyJson] = {
val key2Reads: Reads[Either[String, Map[String, String]]] =
(__ \ "key2").read[String].map(Left(_)) or
(__ \ "key2").read[Map[String, String]].map(Right(_))
((__ \ "key1").read[String] and key2Reads)(MyJson(_, _))
}
Which works like this:
scala> Json.parse(jsonString).as[List[MyJson]].foreach(println)
MyJson(v1,Left(v2))
MyJson(x1,Left(x2))
MyJson(y1,Right(Map(subkey1 -> subval1, subkey2 -> subval2)))
Yes, this is a little more verbose, but it's up-front verbosity that you pay for once (and that provides you with some nice guarantees), instead of a bunch of casts that can result in confusing runtime errors.
It's not for everyone, and it may not be to your taste—that's perfectly fine. You can use the path operators to handle cases like this, or even plain old Jackson. I'd encourage you to give the type class approach a chance, though—there's a steep-ish learning curve, but lots of people (including myself) very strongly prefer it.
I've chosen to use Jackson module for scala.
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val obj = mapper.readValue[Map[String, Object]](jsonString)
For further reference and in the spirit of simplicity, you can always go for:
Json.parse(jsonString).as[Map[String, JsValue]]
However, this will throw an exception for JSON strings not corresponding to the format (but I assume that goes for the Jackson approach as well). The JsValue can now be processed further like:
jsValueWhichBetterBeAList.as[List[JsValue]]
I hope the difference between handling Objects and JsValues is not an issue for you (only because you were complaining about JsValues being proprietary). Obviously, this is a bit like dynamic programming in a typed language, which usually isn't the way to go (Travis' answer is usually the way to go), but sometimes that's nice to have I guess.
You can simply extract out the value of a Json and scala gives you the corresponding map.
Example:
var myJson = Json.obj(
"customerId" -> "xyz",
"addressId" -> "xyz",
"firstName" -> "xyz",
"lastName" -> "xyz",
"address" -> "xyz"
)
Suppose you have the Json of above type.
To convert it into map simply do:
var mapFromJson = myJson.value
This gives you a map of type : scala.collection.immutable.HashMap$HashTrieMap
Would recommend reading up on pattern matching and recursive ADTs in general to better understand of why Play Json treats JSON as a "first class citizen".
That being said, many Java-first APIs (like Google Java libraries) expect JSON deserialized as Map[String, Object]. While you can very simply create your own function that recursively generates this object with pattern matching, the simplest solution would probably be to use the following existing pattern:
import com.google.gson.Gson
import java.util.{Map => JMap, LinkedHashMap}
val gson = new Gson()
def decode(encoded: String): JMap[String, Object] =
gson.fromJson(encoded, (new LinkedHashMap[String, Object]()).getClass)
The LinkedHashMap is used if you would like to maintain key ordering at the time of deserialization (a HashMap can be used if ordering doesn't matter). Full example here.

json parsing problems

data: [
{
type: "earnings"
info: {
earnings: 45.6
dividends: 4052.94
gains: 0
expenses: 3935.24
shares_bought: 0
shares_bought_user_count: 0
shares_sold: 0
shares_sold_user_count: 0
}
created: "2011-07-04 11:46:17"
}
{
type: "mentions"
info: [
{
type_id: "twitter"
mentioner_ticker: "LOANS"
mentioner_full_name: "ERICK STROBEL"
}
]
created: "2011-06-10 23:03:02"
}
]
Here's my problem : like you can see the "info" is different in each of one, one is a json object, and one is a json array, i usually choose Gson to take the data, but with Gson we can't do this kind of thing . How can i make it work ?
If you want to use Gson, then to handle the issue where the same JSON element value is sometimes an array and sometimes an object, custom deserialization processing is necessary. I posted an example of this in the Parsing JSON with GSON, object sometimes contains list sometimes contains object post.
If the "info" element object has different elements based on type, and so you want polymorphic deserialization behavior to deserialize to the correct type of object, with Gson you'll also need to implement custom deserialization processing. How to do that has been covered in other StackOverflow.com posts. I posted a link to four different such questions and answers (some with code examples) in the Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied thread. In this thread, the particular structure of the JSON objects to deserialize varies from the examples I just linked, because the element to indicate the type is external of the object to be deserialized, but if you can understand the other examples, then handling the problem here should be easy.
Both key and value have to be within quotes, and you need to separate definitions with commas:
{
"key0": "value0",
"key1": "value1",
"key2": [ "value2_0", "value2_1" ]
}
That should do the trick!
The info object should be of the same type with every type.
So check the type first. Pseudocode:
if (data.get('type').equals("mentions") {
json_arr = data.get('info');
}
else if (data.get('type').equals("earnings") {
json_obj = data.get('info');
}
I'm not sure that helps, cause I'm not sure I understand the question.
Use simply org.json classes that are available in android: http://developer.android.com/reference/org/json/package-summary.html
You will get a dynamic structure that you will be able to traverse, without the limitations of strong typing.....
This is not a "usual" way of doing things in Java (where strong typing is default) but IMHO in many situations even in Java it is ok to do some dynamic processing. Flexibility is better but price to pay is lack of compile-time type verification... Which in many cases is ok.
If changing libraries is an option you could have a look at Jackson, its Simple Data Binding mode should allow you to deserialize an object like you describe about. A part of the doc that is probably quite important is this, your example would already need JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES to work...
Clarification for Bruce: true, in Jackson's Full Data Binding mode, but not in Simple Data Binding mode. This is simple data binding:
public static void main(String[] args) throws IOException {
File src = new File("test.json");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature. ALLOW_UNQUOTED_FIELD_NAMES, true);
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);
Object root = mapper.readValue(src, Object.class);
Map<?,?> rootAsMap = mapper.readValue(src, Map.class);
System.out.println(rootAsMap);
}
which with OP's sightly corrected sample JSON data gives:
{data=[{type=earnings, info={earnings=45.6, dividends=4052.94, gains=0,
expenses=3935.24, shares_bought=0, shares_bought_user_count=0, shares_sold=0,
shares_sold_user_count=0}, created=2011-07-04 11:46:17}, {type=mentions,
info=[{type_id=twitter, mentioner_ticker=LOANS, mentioner_full_name=ERICK STROBEL}],
created=2011-06-10 23:03:02}]}
OK, some hand-coding needed to wire up this Map to the original data, but quite often less is more and such mapping code, being dead simple has the advantage of being very easy to read/maintain later on.

Generate Java class from JSON?

In a Java Maven project, how do you generate java source files from JSON? For example we have
{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York"
}
}
When we run mvn generate-sources we want it to generate something like this:
class Address {
JSONObject mInternalJSONObject;
Address (JSONObject json){
mInternalJSONObject = json;
}
String getStreetAddress () {
return mInternalJSONObject.getString("streetAddress");
}
String getCity (){
return mInternalJSONObject.getString("city");
}
}
class Person {
JSONObject mInternalJSONObject;
Person (JSONObject json){
mInternalJSONObject = json;
}
String getFirstName () {
return mInternalJSONObject.getString("firstName");
}
String getLastName (){
return mInternalJSONObject.getString("lastName");
}
Address getAddress (){
return Address(mInternalJSONObject.getString("address"));
}
}
As a Java developer, what lines of XML do I need to write in my pom.xml in order to make this happen?
Try http://www.jsonschema2pojo.org
Or the jsonschema2pojo plug-in for Maven:
<plugin>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>1.0.2</version>
<configuration>
<sourceDirectory>${basedir}/src/main/resources/schemas</sourceDirectory>
<targetPackage>com.myproject.jsonschemas</targetPackage>
<sourceType>json</sourceType>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
The <sourceType>json</sourceType> covers the case where the sources are json (like the OP). If you have actual json schemas, remove this line.
Updated in 2014: Two things have happened since Dec '09 when this question was asked:
The JSON Schema spec has moved on a lot. It's still in draft (not finalised) but it's close to completion and is now a viable tool specifying your structural rules
I've recently started a new open source project specifically intended to solve your problem: jsonschema2pojo. The jsonschema2pojo tool takes a json schema document and generates DTO-style Java classes (in the form of .java source files). The project is not yet mature but already provides coverage of the most useful parts of json schema. I'm looking for more feedback from users to help drive the development. Right now you can use the tool from the command line or as a Maven plugin.
If you're using Jackson (the most popular library there), try
https://github.com/astav/JsonToJava
Its open source (last updated on Jun 7, 2013 as of year 2021) and anyone should be able to contribute.
Summary
A JsonToJava source class file generator that deduces the schema based on supplied sample json data and generates the necessary java data structures.
It encourages teams to think in Json first, before writing actual code.
Features
Can generate classes for an arbitrarily complex hierarchy (recursively)
Can read your existing Java classes and if it can deserialize into those structures, will do so
Will prompt for user input when ambiguous cases exist
Here's an online tool that will take JSON, including nested objects or nested arrays of objects and generate a Java source with Jackson annotations.
Answering this old question with recent project ;-).
At the moment the best solution is probably JsonSchema2Pojo :
It does the job from the seldom used Json Schema but also with plain Json. It provides Ant and Maven plugin and an online test application can give you an idea of the tool. I put a Json Tweet and generated all the containing class (Tweet, User, Location, etc..).
We'll use it on Agorava project to generate Social Media mapping and follow the contant evolution in their API.
Thanks all who attempted to help. For me this script was helpful. It process only flat JSON and don't take care of types, but automate some routine
String str =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";
JSONObject json = new JSONObject(str);
Iterator<String> iterator = json.keys();
System.out.println("Fields:");
while (iterator.hasNext() ){
System.out.println(String.format("public String %s;", iterator.next()));
}
System.out.println("public void Parse (String str){");
System.out.println("JSONObject json = new JSONObject(str);");
iterator = json.keys();
while (iterator.hasNext() ){
String key = iterator.next();
System.out.println(String.format("this.%s = json.getString(\"%s\");",key,key ));
System.out.println("}");
I'm aware this is an old question, but I stumbled across it while trying to find an answer myself.
The answer that mentions the online json-pojo generator (jsongen) is good, but I needed something I could run on the command line and tweak more.
So I wrote a very hacky ruby script to take a sample JSON file and generate POJOs from it. It has a number of limitations (for example, it doesn't deal with fields that match java reserved keywords) but it does enough for many cases.
The code generated, by default, annotates for use with Jackson, but this can be turned off with a switch.
You can find the code on github: https://github.com/wotifgroup/json2pojo
I created a github project Json2Java that does this.
https://github.com/inder123/json2java
Json2Java provides customizations such as renaming fields, and creating inheritance hierarchies.
I have used the tool to create some relatively complex APIs:
Gracenote's TMS API: https://github.com/inder123/gracenote-java-api
Google Maps Geocoding API: https://github.com/inder123/geocoding
I had the same problem so i decided to start writing a small tool to help me with this. Im gonna share andopen source it.
https://github.com/BrunoAlexandreMendesMartins/CleverModels
It supports, JAVA, C# & Objective-c from JSON .
Feel free to contribute!
I know there are many answers but of all these I found this one most useful for me. This link below gives you all the POJO classes in a separate file rather than one huge class that some of the mentioned websites do:
https://json2csharp.com/json-to-pojo
It has other converters too. Also, it works online without a limitation in size. My JSON is huge and it worked nicely.
As far as I know there is no such tool. Yet.
The main reason is, I suspect, that unlike with XML (which has XML Schema, and then tools like 'xjc' to do what you ask, between XML and POJO definitions), there is no fully features schema language. There is JSON Schema, but it has very little support for actual type definitions (focuses on JSON structures), so it would be tricky to generate Java classes. But probably still possible, esp. if some naming conventions were defined and used to support generation.
However: this is something that has been fairly frequently requested (on mailing lists of JSON tool projects I follow), so I think that someone will write such a tool in near future.
So I don't think it is a bad idea per se (also: it is not a good idea for all use cases, depends on what you want to do ).
You could also try GSON library. Its quite powerful it can create JSON from collections, custom objects and works also vice versa. Its released under Apache Licence 2.0 so you can use it also commercially.
http://code.google.com/p/google-gson/
Try my solution
http://htmlpreview.github.io/?https://raw.githubusercontent.com/foobnix/android-universal-utils/master/json/generator.html
{
"auctionHouse": "sample string 1",
"bidDate": "2014-05-30T08:20:38.5426521-04:00 ",
"bidPrice": 3,
"bidPrice1": 3.1,
"isYear":true
}
Result Java Class
private String auctionHouse;
private Date bidDate;
private int bidPrice;
private double bidPrice1;
private boolean isYear;
JSONObject get
auctionHouse = obj.getString("auctionHouse");
bidDate = obj.opt("bidDate");
bidPrice = obj.getInt("bidPrice");
bidPrice1 = obj.getDouble("bidPrice1");
isYear = obj.getBoolean("isYear");
JSONObject put
obj.put("auctionHouse",auctionHouse);
obj.put("bidDate",bidDate);
obj.put("bidPrice",bidPrice);
obj.put("bidPrice1",bidPrice1);
obj.put("isYear",isYear);
To add to #japher's post. If you are not particularly tied to JSON, Protocol Buffers is worth checking out.

Categories