Hello all sorry my language is Bad!
This is my code:
MyCustomClass temp = new MyCustomClass();
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
temp.ID = obj.getInt("ID");
temp.PicName = obj.getString("PicName");
temp.PicURL = obj.getString("PicURL");
Items.add(temp);
}
I would like to take this dynamic
Something like this
MyCustomClass temp = new MyCustomClass();
Field[] myFields= MyCustomClass.class.getFields();
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
for(int j=0;j<myFields.lenghth();j++)
{
myFields[j]=obj.getString(myFields[j].toString());
Items.add(temp);
}
}
How to do it?
*Name of jason fields = Name of MycustomClass Fields
Jackson and Gson will do all this for you.
static class TestClass {
public int id;
public String name;
}
#Test
public void gson() {
Gson gson = new Gson();
TestClass[] item = gson.fromJson("[{'id': 1, 'name': 'testclass'}]", TestClass[].class);
assertThat(item[0].id, is(1));
assertThat(item[0].name, is("testclass"));
assertThat(item.length, is(1));
}
#Test
public void jackson() throws IOException {
ObjectMapper jacksonObjectMapepr = new ObjectMapper();
TestClass[] item = jacksonObjectMapepr.readValue("[{\"id\": 1, \"name\": \"testclass\"}]", TestClass[].class);
assertThat(item[0].id, is(1));
assertThat(item[0].name, is("testclass"));
assertThat(item.length, is(1));
}
However to answer your question, you can look up what each field with getDeclaredField. But you will have to do quite some work to handle all the type mapping.
#Test
public void sillyWayIDontRecommend() throws NoSuchFieldException, IllegalAccessException {
TestClass[] item = new TestClass[1];
JsonArray array = new JsonParser().parse("[{\"id\": 1, \"name\": \"testclass\"}]").getAsJsonArray();
for(int i = 0; i<array.size(); i++) {
item[i] = new TestClass();
JsonObject object = array.get(i).getAsJsonObject();
for(Map.Entry<String, JsonElement> entry : object.entrySet()) {
Field field = TestClass.class.getDeclaredField(entry.getKey());
if(field.getType().equals(int.class)) {
field.setInt(item[i], entry.getValue().getAsInt());
} else {
field.set(item[i], entry.getValue().getAsString());
}
}
}
assertThat(item[0].id, is(1));
assertThat(item[0].name, is("testclass"));
assertThat(item.length, is(1));
}
With jackson library you are able to set up your Pojos directly with json annotations and you are able to convert your JSON strings directly to java objects.
A generic way for parsing can be something like that:
public static <T> T deserialize(T t, Class<T> clazz, String json) throws JsonParseException, JsonMappingException, IOException{
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(json, clazz);
}
T - is your object and return type
clazz - is your Pojo
json - is your json String
You can call the method like this:
MyCustomClass myCustomClass= new MyCustomClass();
myCustomClass= JsonUtil.deserialize(myCustomClass, MyCustomClass.class, json);
Your Pojo can look like this:
#JsonIgnoreProperties // ignores properties from json String which are not in your Pojo
public class MyCustomClass {
#JsonProperty("anotherNameIfFieldNameIsNotEqual")
private String picName;
private String picURL;
public String getPicName() {
return picName;
}
public void setPicName(String picName) {
this.picName = picName;
}
public String getPicURL() {
return picURL;
}
public void setPicURL(String picURL) {
this.picURL= picURL;
}
}
And this is the maven dependency you need:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
Documentation and Example
You can get all class field with this construction:
Class class = ...//obtain class object
Field[] methods = class.getFields();
With your class it's:
MyCustomClass temp = new MyCustomClass();
Field[] methods = temp.getFields();
Related
I have a json file, for example:
{
"A":"-0.4",
"B":"-0.2",
"C":"-0.2",
"D":"X",
"E":"0.2",
"F":"0.2",
"J":"0.3"
}
I want return each element of a list json when I call it via my function.
I did a function to do this:
public JSONObject my_function() {
JSONParser parser = new JSONParser();
List<JSONObject> records = new ArrayList<JSONObject>();
try (FileReader reader = new FileReader("File.json")) {
//Read JSON file
Object obj = parser.parse(reader);
JSONObject docs = (JSONObject) obj;
LOGGER.info("read elements" + docs); // it display all a list of a json file like this: {"A":"-0.4","B":"-0.2","C":"-0.2","D":"X","E":"0.2","F":"0.2","J":"0.3"}
for (int i = 0; i < docs.size(); i++) {
records.add((JSONObject) docs.get(i));
System.out.println((records)); // it return null
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
LOGGER.info("The first element of a list is:" +records.get(0)); // return null
return records.get(0);
How can I change my function to return the value of each element in a json file.
For example, when I call my_function:
my_function.get("A") should display -0.4
Thank you
First you need a Class for mapping
public class Json {
private String a;
private String b;
private String c;
private String d;
private String e;
private String f;
private String j;
//getters and setters
}
Then in your working class
ObjectMapper mapper = new ObjectMapper();
//JSON from file to Object
Json jsn = mapper.readValue(new File("File.json"), Json.class);
then you can use that object in a usual way...
here is the dependency I used
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
Reference
In Java you can use only class`s methods, as I know.
If you want to get your second element by its first, you should in your class create 2 methods like
class Main {
Map<String, String> records = new HashMap<>();
public JSONObject my_function() {
// your realization where you should insert your pairs into Map.
}
public String get(String firstElement){
return map.getValue(firstElement);
}
}
class someOtherClass {
Main main = new Main();
main .my_function();
main .get("A");
}
How we convert following type of json into java object
{
"complaint_Map": {
"1000067730": "3011351597604397",
"1000067730-06": "10582576134561065"
}
}
if anyone have any idea about this tell how we do that.
With jackson
import com.fasterxml.jackson.databind.ObjectMapper;
Try
ObjectMapper mapper = new ObjectMapper();
String jsonInString = "{\"complaint_Map\":{\"1000067730\":\"3011351597604397\",\"1000067730-06\":\"10582576134561065\"}}";
Map<String,Object> pojo = mapper.readValue(jsonInString, Map.class);
System.out.println(((Map<String,Object>)pojo.get("complaint_Map")).get("1000067730")+"");
will print
3011351597604397
In java you can use Jackson library that converts a simple POJO to/from JSON.
From Wikipedia:
Jackson is a high-performance JSON processor for Java. Developers of it extol the combination of fast, correct, lightweight, and ergonomic attributes of the library.
Here an example taken by Wikipedia:
public class ReadWriteJackson {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String jsonInput =
"{\"id\":0,\"firstName\":\"Robin\",\"lastName\":\"Wilson\"}";
Person q = mapper.readValue(jsonInput, Person.class);
System.out.println("Read and parsed Person from JSON: " + q);
Person p = new Person("Roger", "Rabbit");
System.out.print("Person object " + p + " as JSON = ");
mapper.writeValue(System.out, p);
}
}
You can do it with ObjectMapper from jackson.
Suppose the json is defines a java object,
then it can be done by
import org.codehaus.jackson.map.ObjectMapper;
YourObject mappingClassObject = new YourObject();
ObjectMapper mapper = new ObjectMapper();
try{
mappingClassObject = mapper.readValue(yourJSON, YourObject.class);
}catch(Exception e){
e.printStackTrace();
}
If you want a solution using Jackson library, here it is.
The custom class:
#JsonRootName("complaint_Map")
public class Complaint {
private String firstKey;
private String secondKey;
#JsonProperty("1000067730")
public String getFirstKey() {
return firstKey;
}
#JsonProperty("1000067730")
public void setFirstKey(String firstKey) {
this.firstKey = firstKey;
}
#JsonProperty("1000067730-06")
public String getSecondKey() {
return secondKey;
}
#JsonProperty("1000067730-06")
public void setSecondKey(String secondKey) {
this.secondKey = secondKey;
}
#Override
public String toString() {
return "Complaint{" +
"firstKey='" + firstKey + '\'' +
", secondKey='" + secondKey + '\'' +
'}';
}
}
And the way of testing:
String jsonString = "{\"complaint_Map\":{\"1000067730\":\"3011351597604397\",\"1000067730-06\":\"10582576134561065\"}}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
try {
Complaint complaint = mapper.readValue(jsonString, Complaint.class);
System.out.println(complaint);
} catch (Exception e) {
e.printStackTrace();
}
I used the following version (in Maven pom):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.3</version>
</dependency>
So I got this piece of code:
public static ArrayList<Vehicle> readVehicles() throws IOException {
ArrayList<Vehicle> out = new ArrayList<Vehicle>();
JSONParser parser = new JSONParser();
JSONObject jsonObject = new JSONObject();
try {
jsonObject = (JSONObject) parser.parse(new FileReader("Vehicles.json"));
} catch (ParseException e) {
e.printStackTrace();
}
JSONArray jsonvehicles = (JSONArray) jsonObject.get("Vehicles");
Iterator i = jsonvehicles.iterator();
while (i.hasNext()) {
JSONObject v = (JSONObject) i.next();
/*
* Engines(); Chassis(); Tires();
*/
// out.add(new Vehicle(...);
}
return out;
}
public static ArrayList<Engine> readEngines() throws IOException {
ArrayList<Engine> out = new ArrayList<Engine>();
JSONParser parser = new JSONParser();
JSONObject jsonObject = new JSONObject();
try {
jsonObject = (JSONObject) parser.parse(new FileReader("Engines.json"));
} catch (ParseException e) {
e.printStackTrace();
}
JSONArray jsonengines = (JSONArray) jsonObject.get("Engines");
Iterator i = jsonengines.iterator();
while (i.hasNext()) {
JSONObject v = (JSONObject) i.next();
String name = (String) v.get("name");
int price = (int) v.get("price");
int quality = (int) v.get("quality");
int maxSpeed = (int) v.get("maxSpeed");
int maxAccelaration = (int) v.get("maxAcceleration");
out.add(new Engine(name, price, quality, maxSpeed, maxAccelaration));
}
return out;
}
and so on, regarding at tires(), and chassis.
My question is, how do I get the output of for example, engine, into vehicle?
See, a vehicle consists of engines, chassis and tires. And a engine as the properties quality, name, price and so on. How do I kinda add this to a new vehicle?
It's probably already been asked, but I really don't know how to ask this (native language isn't English). Sorry if I sound really vague, but to be honest, I'm not sure what I'm asking.
As Kevin Esche said, you can do it by something like this (For example) :
Car.java class file
private class Car{
private Engine engine;
private ArrayList<Tire> tires;
public void setEngine(Engine carEngine){
this.engine = carEngine;
}
public Engine getEngine(){
return this.engine;
}
public void addTire(Tire carTire){
this.tires.add(carTire);
}
}
Engin java class file
private class Engine{
private int horsepower;
public int getHorsepower() {
return horsepower;
}
public void setHorsepower(int horsepower) {
this.horsepower = horsepower;
}
}
Tire.java file
private class Tire{
private int size;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
In addition, something is missing in your "readVehicle()" method code.
You need to write how to build a Vehicule from your Json Object.
So if your json file looks like :
{
"carType": "Mercedes Classe B"
}
you will need to write in your code (readVehicle() method for example):
Vehicule vehicule = new Vehicle();
vehicule.setType(object.getString("carType"));
I want to extract JSON structure (only keyNames structure) by preserving the hierarchy (parent child relationship); I don't want values from the JSON yet.
I am new to Java and have been tying to achieve this using Jackson , but with no success.
Any direction on this will be much appreciated.
I created a static inner class for you by using JSONObject (http://www.json.org/javadoc/org/json/JSONObject.html)
public static class KeyNode {
private String name;
private ArrayList<KeyNode> children;
public KeyNode(String name) {
this.name = name;
this.children = new ArrayList<KeyNode>();
}
public void addChild(KeyNode child) {
this.children.add(child);
}
public static void parseJsonToKeys(KeyNode node, JSONObject json) throws JSONException {
Iterator<?> keys = json.keys();
while (keys.hasNext()) {
String name = (String) keys.next();
KeyNode child = new KeyNode(name);
node.addChild(child);
if (json.optJSONObject(name) != null) {
parseJsonToKeys(child, json.getJSONObject(name));
} else if (json.optJSONArray(name) != null) {
JSONArray array = json.getJSONArray(name);
for (int i = 0; i < array.length(); i++) {
try {
array.getJSONObject(i);
parseJsonToKeys(child, json.getJSONObject(name));
} catch (JSONException e) {
// this is ok
}
}
}
}
}
public static void exampleCodeUsage() {
try {
JSONObject json = new JSONObject("your json");
KeyNode keyHierarchy = new KeyNode("root");
parseJsonToKeys(keyHierarchy, json);
} catch (JSONException e) {
// your json is not formatted correctly
}
}
}
JSONParser parser = parser;
Object obj = parser.parse(new FileReader(FileName.Json));
JSONObject jobj = (JSONObject) obj;
obj.keys()
The method will give you the list of all keys in JSONObject
We use XStream to serialize objects to JSON and vice versa.
We init xStream like this
XStream xStream = new XStream(new JettisonMappedXmlDriver(new Configuration(), false));
xStream.ignoreUnknownElements();
xStream.setMode(XStream.XPATH_RELATIVE_REFERENCES);
We have test class
public static class TestWOWithBI implements Serializable{
private static final long serialVersionUID = -4720678317857471031L;
private transient String customerNickname;
private transient String customerUuid;
private transient BigInteger discussionId;
private transient String message;
public TestWOWithBI(String customerNickname, String customerUuid, BigInteger discussionId, String message){
this.customerNickname = customerNickname;
this.customerUuid = customerUuid;
this.discussionId = discussionId;
this.message = message;
}
private final void writeObject(final ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(customerNickname);
out.writeObject(customerUuid);
out.writeObject(discussionId);
out.writeObject(message);
}
private final void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException{
in.defaultReadObject();
customerNickname = (String) in.readObject();
customerUuid = (String) in.readObject();
discussionId = (BigInteger) in.readObject();
message = (String) in.readObject();
}
}
After serialization it looks like this:
{
"somethere.ObjectToJSONSerializerTest$TestWOWithBI": {
"#serialization": "custom",
"somethere.ObjectToJSONSerializerTest$TestWOWithBI": {
"default": "",
"string": ["name",
"uuid",
"message"],
"big-int": 1
}
}
}
and deserialization fails with class cast. It was on 1.3.1 and 1.4.7 versions. Looks like bug to me, but may be where is some settings?
UPD:
Seems like org.codehaus.jettison.mapped.MappedXMLStreamWriter.JSONPropertyObject#withProperty
if(old != null) {
JSONArray values;
// Convert an existing property to an array
// and append to the array
if (old instanceof JSONArray) {
values = (JSONArray)old;
} else {
values = new JSONArray();
values.put(old);
}
values.put(value);
object.put(property.getKey(), values);
} else if(getSerializedAsArrays().contains(property.getKey())) {
JSONArray values = new JSONArray();
values.put(value);
object.put(property.getKey(), values);
} else {
// Add the property directly.
object.put(property.getKey(), value);
}
It just group elements of same type.