How to modify content of json file? - java

is there any option to modify content of json file? I have 2 methods, export to json file list of different objects, and import from file.
public static void exportShapeListToJson(List<Shape> list, String path) throws IOException {
ObjectMapper mapper = new ObjectMapper();
File file = new File(path);
mapper.enableDefaultTyping();
mapper.writeValue(new File(file.getName()), list);
}
public static List<Shape> importFromJson(String path) throws IOException {
File file = new File(path);
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
return mapper.readValue(file, ArrayList.class);
}
Saved data in file looks like:
["Project1.shapeService.models.Circle",{"radius":3.0}],["Project1.shapeService.models.Circle",{"radius":5.0}],["Project1.shapeService.models.Rectangle",{"a":1.0,"b":2.0}]
Can i modify that data to form like that:
[{"type": "squre", "a": 10}, {"type": "circle", "r": 10}]
and still use method to import? What have to add/ change?

Related

Jackson doesn't append new JSON object to exisiting Json file

I'm trying to build a Springboot app that allows to insert Json object from Postman and save it to existing json file that has other data. I'm new to Jackson so perhaps I missed something?
this is how my json file looks:
[
{
"Name":"After Dark",
"Author":"Haruki Murakami"
},
{
"Name":"It",
"Author":"Stephen King"
}
]
This is what I have tried:
#PostMapping("/insertBook")
public void insertBook(#RequestBody Book book) {
File booksJsonFile = Paths.get(this.getClass().getResource("/books.json").toURI()).toFile();
objectMapper.writeValue(booksJsonFile, book);
}
It's inserts to an empty file but it's doesn't append to existing json file.
I also have tried this:
#PostMapping("/insertBook")
public void insertBook(#RequestBody Book book) throws URISyntaxException {
try {
File file = Paths.get(this.getClass().getResource("/books.json").toURI()).toFile();
FileWriter fileWriter = new FileWriter(file, true);
SequenceWriter seqWriter = objectMapper.writer().writeValuesAsArray(fileWriter);
seqWriter.write(book);
seqWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
This is what I'm sending from Postman:
Do I need to use something else to achieve the result that I want?
I will be thankfull for your help.
I have tried to reproduce your problem according to your code and I come to following conclusions:
You can not modify file under resources directly. Here is explanation why.
I managed to append new JSON to the file (using your approach but saving file locally) but it's probably not what you expect (json structure is corrupted):
[
{
"Name":"After Dark",
"Author":"Haruki Murakami"
},
{
"Name":"It",
"Author":"Stephen King"
}
][{"Name":"new name","Author":"new author"}]
I am afraid that it is not possible to update current JSON structure directly in the file.
I managed to solve your problem using org.json library. However, the disadvantage of my solution is necessity of rewriting entire file each time. In addition I used synchronized keyword in order to avoid simultaneous file modification.
public synchronized void updateJsonFile(Book book) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
Path path = Paths.get("./books.json");
final String currentJsonArrayAsString = Files.readString(path);
try (FileWriter fileWriter = new FileWriter(path.toFile(), false)) {
JSONObject jsonObject = new JSONObject(objectMapper.writeValueAsString(book));
JSONArray jsonArray = new JSONArray(currentJsonArrayAsString);
jsonArray.put(jsonObject);
fileWriter.write(jsonArray.toString());
}
}
And now the books.json has following content:
[
{
"Author":"Haruki Murakami",
"Name":"After Dark"
},
{
"Author":"Stephen King",
"Name":"It"
},
{
"Author":"new author",
"Name":"new name"
}
]

GSON returns StackOverflowError: null

I'm trying to transform my HashMap into a JSON string using Google's lib. GSON.
I've tried using Jackson's ObjectMapper but it didn't work either. I've tried to put some transient and some things I found on other topics without success.
It is currently returning an error (without any line specified):
//ERROR
java.lang.StackOverflowError: null
at sun.reflect.misc.ReflectUtil.checkPackageAccess(Unknown Source) ~[?:1.8.0_201]
at sun.reflect.misc.ReflectUtil.checkPackageAccess(Unknown Source) ~[?:1.8.0_201]
at sun.reflect.generics.reflectiveObjects.TypeVariableImpl.getGenericDeclaration(Unknown Source) ~[?:1.8.0_201]
at com.google.gson.internal.$Gson$Types.declaringClassOf($Gson$Types.java:427) ~[$Gson$Types.class:?]
at com.google.gson.internal.$Gson$Types.resolveTypeVariable($Gson$Types.java:397) ~[$Gson$Types.class:?]
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:329) ~[$Gson$Types.class:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:158) ~[ReflectiveTypeAdapterFactory.class:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100) ~[ReflectiveTypeAdapterFactory.class:?]
at com.google.gson.Gson.getAdapter(Gson.java:423) ~[Gson.class:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:115) ~[ReflectiveTypeAdapterFactory.class:?]
// HashMap I need in JSON
public class Storage {
static #Getter #Setter HashMap<World, HashMap<Chunk, List<Particle>>> storage = new HashMap<>();
}
// Class to load/save the data file
public class StorageManager {
public static File folder, config;
private static final Gson GSON = new Gson();
public static void setup(File _folder){
folder = _folder;
}
public static void load() throws IOException {
if(!folder.exists())
folder.mkdir();
config = new File(folder, "particles.json");
if(!config.exists()) {
config.createNewFile();
FileWriter writer = new FileWriter(config, false);
writer.write(GSON.toJson(Storage.getStorage()));
writer.close();
}
FileReader content = new FileReader(config);
Type type = new TypeToken<HashMap<World, HashMap<Chunk, List<Particle>>>>(){}.getType();
Storage.setStorage(GSON.fromJson(content, type));
}
public static void save() throws IOException {
String json = GSON.toJson(Storage.getStorage());
FileWriter writer = new FileWriter(config, false);
writer.write(json);
writer.close();
}
}
I need to be able to load the file, get the JSON and replace my currently empty Hashmap with the data from the file. I also need to save the file with the new Hashmap data.

Can not deserialize instance of parseJason when using Jackson to parse the Json File

I have a Json file :
[
{
"name":"Move",
"$$hashKey":"object:79",
"time":11.32818,
"endTime":18.615535
},
{
"name":"First Red Flash",
"$$hashKey":"object:77",
"time":15.749153
},
{
"name":"Pills",
"subEventTypes":[
"pull down bottle",
"unscrew lid",
"dump pills out",
"screw lid on",
"put bottle away"
],
"$$hashKey":"object:82",
"time":25.130175,
"subEventSplits":[
26.092057,
27.425881,
31.841594,
34.268093
],
"endTime":36.234827
}
]
I tried to parse this Json file using the Jackson.
I wrote the following code:
public class Holder{
public Holder(){};
//getter and setters
String name;
List<String> subEventTypes = new ArrayList<>();
Double time;
String $$hashKey;
Double endTime;
List<Double> subEventSplits = new ArrayList<>();
}
class MapperClass{
List<Holder> list = new ArrayList<>();
}
public static void main(String[] args) throws JsonProcessingException, IOException
{
ObjectMapper mapper = new ObjectMapper();
List<Holder> list = mapper.readValue(new File("data.json"), mapper.getTypeFactory().constructCollectionType(
List.class, Holder.class));
}
When I run the program, it showed this error : "
No suitable constructor found for type [simple type, class parseJason$Holder]: can not instantiate from JSON object (need to add/enable type information?)
".
Is there anything wrong with my code? or I have to use another way to parse my Json file.
try
list = mapper.readValue(
jsonString,
objectMapper.getTypeFactory().constructCollectionType(
List.class, Holder.class));

SerializationFeature.INDENT_OUTPUT ignored on Jackson 2.6.5

I'm using Jackson mapper version 2.6.5 with Spring Boot but I can seem to get SerializationFeature.INDENT_OUTPUT to work. I'm following the tutorial here. My code is as follows.
public class SerializationExampleTreeModel {
public static void main(String[] args) throws IOException {
// Create the node factory that gives us nodes.
JsonNodeFactory nodeFactory = new JsonNodeFactory(false);
StringWriter stringWriter = new StringWriter();
// create a json factory to write the treenode as json. for the example
// we just write to console
JsonFactory jsonFactory = new JsonFactory();
JsonGenerator generator = jsonFactory.createGenerator(stringWriter);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
// the root node - album
JsonNode album = nodeFactory.objectNode();
album.put("Album-Title", "Kind Of Blue")
ArrayNode songs = nodeFactory.arrayNode()
songs.add("Song8").add("Song2")
album.put("Songs", songs)
ObjectNode artist = nodeFactory.objectNode()
artist.put("Name", "Alex" )
album.put( "artist", artist)
mapper.writeTree(generator, album)
println stringWriter.toString()
}
}
I always get the result:
{"Album-Title":"Kind Of Blue","Songs":["Song8","Song2"],"artist":{"Name":"Alex"}} whether I include the line mapper.configure(SerializationFeature.INDENT_OUTPUT, true) or not. What is going on?
Note: I'm compiling my code using groovyc and semi-colons aren't required.
The problem is you are using StringWriter to write the output and it ignores the formatting you set on ObjectMapper as expected. Instead, use:
System.out.println(mapper.writeValueAsString(album));
If you prefer to use as you are using, you can declare the printer like this before writing the tree:
generator.setPrettyPrinter(new DefaultPrettyPrinter());
mapper.writeTree(generator, album);
This will allow the correct output with:
stringWriter.toString()

How read json file, and convert it to POJO using GSON

I need to pass values from a json file to a java class,the json file is like this exemple:
{
"id":1,
"name":"Gold",
"description":"Shiny!",
"spriteId":1,
"consumable":true,
"effectsId":[1]
},
i need to map,i did this:
Items i = new Items();
Map<String, Items> mapaNomes = new HashMap<String, Items>();
mapaNomes.put("Gold",i);
mapaNomes.put("Apple",i );
mapaNomes.put("Clain Mail",i );
I'm new to android Development and I'm probably forgetting something because the following is not working,someone can help in find what`s is wrong?
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Gson gson = new Gson();
Items Items = gson.fromJson((BufferedReader) mapaNomes, Items.class);
1. Create your POJO representation for your Json.
public class MapaNomes() {
String name;
String description;
// etc
public String getName() {
return name;
}
// create your other getters and setters
}
I find this tool is handy for transforming json to POJO. http://www.jsonschema2pojo.org/
2. Read your file.json. Turn it into object
JsonReader reader = new JsonReader(new FileReader("file.json"));
MapaNomes mapaNomes = new Gson().fromJson(reader, MapaNomes.class);
Bonus
I'm thinking that there might be numerous json objects in your file.json such as:
{
"id":1,
"name":"Gold",
"description":"Shiny!",
"spriteId":1,
"consumable":true,
"effectsId":[1]
},
...
{
"id":999,
"name":"Silver",
"description":"Whatever!",
"spriteId":808,
"consumable":true,
"effectsId":[2]
},
If this is the case, then you can do the following:
JsonReader reader = new JsonReader(new FileReader("file.json"));
List<MapaNomes> mapaNomeses = new Gson().fromJson(
reader,
new TypeToken<List<Review>>() {}.getType());
Then you can do whatever you want with each and every one of them
for (MapaNomes mapaNomes : mapaNomeses) {
// whatever
}

Categories