Instantiate objects by configuration file on java - java

I have this object:
public class TheObjectToInstantiate{
public String Name;
public String Surname;
public TheObjectToInstantiate(){
}
}
I want to instantiate an array of TheObjectToInstantiate[] with configuration file:
TheObjectToInstantiate1.Name="Pippo"
TheObjectToInstantiate1.Surname="PippoSurname"
TheObjectToInstantiate2.Name="Pluto"
TheObjectToInstantiate2.Surname="PlutoSurname"
I've tried with
public ConfigReader(){
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("configuration.prop");
prop.load(input);
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = prop.getProperty(key);
......
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
scanning all properties and instatiate object manually.
There are ways or open source wrapper to do this without manually compare all properties?
Thanks

It's easier to use json files and deserialize them with libraries like Jackson. You may also check http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson
and How to use Jackson to deserialise an array of objects
public class TheObjectToInstantiate {
public String Name;
public String Surname;
public TheObjectToInstantiate(){}
}
public class JacksonExample {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
// Convert JSON string from file to Object
TheObjectToInstantiate object = mapper.readValue(new File("G:\\myobject.json"), TheObjectToInstantiate.class);
} catch (IOException e) {
e.printStackTrace();
}
}
json file would be like this:
{
"Name" : "foo",
"Surname" : "bar"
}
you can also deserialize a list of objects:
List<TheObjectToInstantiate> myObjects = mapper.readValue(new File("G:\\myobjectlist.json"), new TypeReference<List<TheObjectToInstantiate>>(){});
[{
"Name" : "foo1",
"Surname" : "bar1"
},
{
"Name" : "foo2",
"Surname" : "bar2"
}]
It also supports more complex structures like nested objects or a List or array of other objects inside your primary object.

Related

Updating Json file when String ist not present in list

I am coding a Discord Giveaway Bot with Java. I am saving all the details of the Giveaway to a JSON file. Now I want to read the entries list and if the Users ID is not in the list I want to add it and save the file.
Here is the Giveaway Class:
public class Giveaway {
private String prize;
private long time;
private Integer winners;
private List<String> entries;
public Giveaway(String prize, Integer winners, long time, List<String> entries) {
this.prize = prize;
this.winners = winners;
this.time = time;
this.entries = entries;
}
public Giveaway() {}
public String getPrize() {
return prize;
}
public void setPrize(String prize) {
this.prize = prize;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public Integer getWinners() {
return winners;
}
public void setWinners(Integer winners) {
this.winners = winners;
}
public List<String> getEntries() {
return entries;
}
public void setEntries(List<String> entries) {
this.entries = entries;
}
}
When the GW is created the JSON looks like this:
{
"prize": "Discord Nitro",
"time": 1641732935,
"winners": 2,
"entries": []
}
Then when the user clicks a button it should read the list look if the ID is in the list and if not add the id. But when I save the list the whole JSON file changes.
How I read it out and save it:
public class ButtonClick extends ListenerAdapter {
private static Reader reader;
private static Giveaway giveaway = new Giveaway();
public void onButtonClick(ButtonClickEvent event) {
event.deferEdit().queue();
try {
reader = Files.newBufferedReader(Path.of(GiveawayStats.getGiveawayStats().getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
}
if (event.getButton().getId().equals("gwEnter")) {
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(reader).getAsJsonObject();
JsonArray jsonEntries = obj.get("entries").getAsJsonArray();
long time = obj.get("time").getAsLong();
List<String> entries = new ArrayList<>();
for (JsonElement entrie : jsonEntries) {
entries.add(entrie.toString());
}
if (entries.contains(event.getMember().getId())) {
event.getChannel().sendMessage("Already in!").queue();
} else {
entries.add(event.getUser().getId().strip());
printToJson(entries);
}
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void printToJson(List<String> entries) {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setVersion(2.0);
Gson gson = gsonBuilder.setPrettyPrinting().create();
giveaway.setEntries(entries);
try (Writer writer = new FileWriter(GiveawayStats.getGiveawayStats().getPath())) {
gson.toJson(giveaway, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
After the print so JSON the file looks like this:
{
"time": 0,
"entries": [
"695629580014321747"
]
}
And when I click the Button again it looks like this:
{
"time": 0,
"entries": [
"\"695629580014321747\"",
"695629580014321747"
]
}
So why is my IF condition not working?
You are using entrie.toString() which gives you the string that is used for console output. You should be using entrie.getAsString() instead.
Furthermore, you are also using a lot of deprecated things with JsonParser which should be replaced. new JsonParser().parse(...) should be replaced by JsonParser.parseReader(...).
Above all that, it is highly recommended using a database for this kind of task. Something such as SQLite or Redis would be much better at handling concurrent changes and redundancy. Or at least, you should use a try-with-resources for your reader.
try (Reader reader = ...) {
JsonElement json = JsonParser.parseReader(reader).getAsJsonObject();
...
}

How do I create a yaml file correctly with eo-yaml

With the help of the api https://github.com/decorators-squad/eo-yaml I create a yaml file however I have the problem that the file format does not fit as I would like to have them
How my config should look like:
name: ali
age: unknown
gender: male
How my Config look:
yaml name: aliage: unknowngender: male
My create methode
for ( Field field : clazz.getDeclaredFields() ) {
if (Modifier.isPrivate(field.getModifiers())) {
field.setAccessible(true);
}
Object value = null;
try {
value = field.get(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
YamlMapping yaml = Yaml.createYamlMappingBuilder()
.add(field.getName(), value.toString()).build();
try {
fileWriter.write(yaml.toString());
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}```
**My ConfigTest Class**
```java
#Configuration(name = "config.yml")
public class ConfigTest extends YamlConfig {
private final String name = "ali";
private final String age = "unknown";
private final String gender = "male";
public ConfigTest() {
this.create();
}
}
You are creating a new YamlMapping for each key/value pair and immediately render it. So you render three separate mappings:
name: ali
age: unknown
gender: male
Then, you concatenate them into a file. Since you do not add line breaks, they are all written to the same line.
What you actually want to do is to create one mapping that contains all three key/value pairs:
YamlMappingBuilder builder = Yaml.createYamlMappingBuilder();
for ( Field field : clazz.getDeclaredFields() ) {
if (Modifier.isPrivate(field.getModifiers())) {
field.setAccessible(true);
}
Object value = null;
try {
value = field.get(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
builder.add(field.getName(), value.toString());
}
try {
fileWriter.write(builder.build().toString());
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}

How can I iterate through JSON objects using Jackson?

I ultimately want to create inverted indexes using my JSON dataset. I know how to parse through one JSON object but how can I iterate through many? Here is what I have working:
File1:
{
"doc_id": "2324jos",
"screen_name": "twitter_user101",
"tweet_text": "Its a beautiful day to be productive",
"hashtags": "[]",
"links": "[]",
"place_type": "city",
"place_name": "Evergreen Park",
"created_at": "2019-02-08 22:24:03"
}
My code:
public class ParseJson {
public static void main(String[] args) throws Exception {
// this is the key object to convert JSON to Java
Tweet tweet;
ObjectMapper mapper = new ObjectMapper();
try {
File json = new File("test.json");
tweet = mapper.readValue(json, Tweet.class);
System.out.println("Java object created from JSON String :");
System.out.println(tweet);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public class Tweet {
public String doc_id;
public String screen_name;
public String tweet_text;
public String hashtags;
public String links;
public String place_type;
public String place_name;
public String created_at;
public Tweet() {
}
public Tweet(String doc_id, String screen_name, String tweet_text, String hashtags, String links, String place_type, String place_name, String created_at) {
this.doc_id = doc_id;
this.screen_name = screen_name;
this.tweet_text = tweet_text;
this.hashtags = hashtags;
this.links = links;
this.place_name = place_name;
this.place_type = place_type;
this.created_at = created_at;
}
#Override
public String toString() {
return doc_id + screen_name + tweet_text;
}
}
Now, I want to iterate through this JSON file which has 2 JSON objects in an array:
File2:
[
{
"doc_id": "2324jos",
"screen_name": "b'LIBBYRULZ'",
"tweet_text": "#ABC ya'll be lying",
"hashtags": "[]",
"links": "[]",
"place_type": "city",
"place_name": "Evergreen Park",
"created_at": "2019-02-08 22:24:03"
},
{
"doc_id": "8982hol",
"screen_name": "b'eddylee_1'",
"tweet_text": "Hungry for money",
"hashtags": "[]",
"links": "[]",
"place_type": "city",
"place_name": "Manhattan",
"created_at": "2/7/2019 17:01"
}
]
How can I adjust my above code using Jackson to do so where the doc_id is the unique key? I want to be able to return all the data in each JSON object for each doc_id.
To parse an array of JSON objects using Jackson:
Tweet[] tweets = mapper.readValue(json, Tweet[].class);
should do the trick. See below:
public class ParseJson {
public static void main(String[] args) throws Exception {
Tweet[] tweets;
ObjectMapper mapper = new ObjectMapper();
try {
File json = new File("test.json");
tweets = mapper.readValue(json, Tweet[].class);
System.out.println("Java object created from JSON String :");
Arrays.asList(tweets).forEach(System.out::println); // Prints each element in the array
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
You could try to put it in a list so you can iterate on it:
List<Tweet> data = mapper.readValue(json, new TypeReference<List<Tweet>>(){});
I would suggest using the TypeFactory to create a CollectionType and use it to parse the JSON as List<Tweet>.
CollectionType tweetListType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, Tweet.class);
List<Tweet> tweets = mapper.readValue(json, tweetListType);
tweets.forEach(System.out::println);
Here is the complete example you shared:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ParseJson {
public static void main(String[] args) {
// this is the key object to convert JSON to Java
ObjectMapper mapper = new ObjectMapper();
try {
File json = new File("test.json");
CollectionType tweetListType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, Tweet.class);
List<Tweet> tweets = mapper.readValue(json, tweetListType);
System.out.println("Java objects created from JSON String:");
tweets.forEach(System.out::println);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

How to map JSON (custom)

I'm a beginner and I need to sort from a JSON to be analyzed later.
I need to know the JSON fields and if it has arrays or subcategories.
I have to map JSON input, for example:
{
"car":"Audi",
"model":"2010",
"price":"30000",
"colors":[
"Grey",
"White",
"Black"
],
"otro":{
"a":1,
"b":2,
"c":[
{
"c11":"c11",
"c12":"c12"
},
{
"c21":"c21",
"c22":"c22"
}
]
}
}
Waiting as output mapping:
car
model
price
colors[]
otro.a
otro.b
otro.c[].c11
otro.c[].c12
otro.c[].c21
otro.c[].c22
This is my code:
public static void main(String[] args) {
try {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"car\":\"Audi\",\"model\":\"2010\",\"price\":\"30000\",\"colors\":[\"Grey\",\"White\",\"Black\"],\"otro\":{\"a\":1,\"b\":2,\"c\":[{\"c11\":\"c11\", \"c12\":\"c12\"},{\"c21\":\"c21\", \"c22\":\"c22\"}]}}";
Map<String, Object> map = new HashMap<String, Object>();
// convert JSON string to Map
map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {
});
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue().getClass());
if (entry.getValue() instanceof List) {
for (Object object : ((List)entry.getValue())) {
System.out.println("\t-- " + object.getClass());
}
}
}
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
You can make a POJO and map the JSON to the POJO and do whatever you would like with it. Another option that is pretty powerful is using the JsonNode objects. They have lots of helper methods for figuring out the types of each node. Here are some quick examples https://www.stubbornjava.com/posts/practical-jackson-objectmapper-configuration#jsonnodes-and-nested-objects

Get the data from the pojo classes of the JSON file

I have the following JSON array as file in my Jersey project in src/main/resources/routes.txt. I want to convert it to Java object to get the time in the case of mon-fri or sat or sun. I have generated the classes below with the help of this link. How can I get the time from the ArrivalTime class with this generated structure? Should I put all these generated classes as inner classes of the root class or separately?
I appreciate any help.
JSON simple:
[{
"route": 1,
"info": {
"stops": {
"arrival_time": {"mon-fri": ["04:24","05:10","05:40"],
"sat": ["05:34","05:55","06:15"],
"sun": ["07:00","08:00","05:40"]
},
"stops_name": "Tension Way"
},
"direction": "Surrey Quays"
}
}]
Generated classes:
public class Root {
private Integer route;
private Info info;
}
public class Info {
private Stops stops;
private String direction;
}
public class Stops {
private ArrivalTime arrivalTime;
private String stopsName;
}
public class ArrivalTime {
private List<String> monFri = new ArrayList<String>();
private List<String> sat = new ArrayList<String>();
private List<String> sun = new ArrayList<String>();
}
Code:
ObjectMapper mapper = new ObjectMapper();
FileReader fileReader;
try {
fileReader = new FileReader("src/main/resources");
try {
Root readValue = mapper.readValue(fileReader, Root.class);
readValue.getInfo();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<String> monFri = readValue().getInfo().getStops().getArrivalTime().getMonFri();
That's the structure of the JSON object, and is also the structure of the Java object mapped to the JSON.
The classes should be top-level classes, or static nested classes, but not inner classes.

Categories

Resources