Gson append object to json file - java

I am currently working on a todo web application using Spring Boot. The problem I'm facing is that whenever I add an item it is not stored in my json file. This is my current json file:
[
{
"id": 0,
"task": "some task"
},
{
"id": 1,
"task": "some other task"
},
{
"id": 2,
"task": "some different task"
}
]
When I add my todo item with the application, it gets added to my dataprovider;
TodoDataProvider.java:
public class TodoDataProvider {
private static TodoDataProvider instance;
private List<TodoItem> todoItems = new ArrayList<>();
public static TodoDataProvider getInstance() {
if (instance == null) {
instance = new TodoDataProvider();
}
//read data from json
Gson gson = new Gson();
try {
FileReader reader = new FileReader("src/main/java/com/example/servingwebcontent/todos.json");
TodoItem[] tempTodos = gson.fromJson(reader, TodoItem[].class);
for (TodoItem tempTodo : tempTodos) {
instance.addTodo(tempTodo);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return instance;
}
... getters and setters
After I try to add this todo my json file becomes empty. What is the best way to add this new json object to the existing json file using gson?
This is the code where I add this item:
TodoController.java
#Controller
public class TodoController {
TodoDataProvider dataProvider = TodoDataProvider.getInstance();
#GetMapping("/")
public String greeting(Model model) {
model.addAttribute("todos", dataProvider.getTodoItems());
return "todo";
}
#PostMapping("/")
public String addTodo(Model model, #RequestParam("todoTask") String todoTask) {
TodoItem todoItem = new TodoItem(4, todoTask);
dataProvider.addTodo(todoItem);
Gson gson = new Gson();
try {
// TODO: 14-7-2022 add to json instead of replace
gson.toJson(dataProvider.getTodoItems(), new FileWriter("src/main/java/com/example/servingwebcontent/todos.json"));
} catch (IOException e) {
System.out.println(e.getMessage());
}
model.addAttribute("todos", dataProvider.getTodoItems());
return "redirect:/";
}
}

Related

How to use gson for getstring of json?

I am new to use gson.
I found a lots of tutorial there I can learn of gson but there are using recylerview and model file.
JsonObjectRequest request = new JsonObjectRequest(LoginUrl, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG , String.valueOf(response));
try {
String statusObject = response.getString("status");
String msgObject = response.getString("msg");
if (statusObject.equals("200")) {
JSONArray jsonArray = response.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject managerResponse= jsonArray.getJSONObject(i);
// userIdObject = managerResponse.getString("user_id");
// String nameObject = managerResponse.getString("name");
// String emailObject = managerResponse.getString("email");
// String mobileObject = managerResponse.getString("mobile");
// String postobject = managerResponse.getString("post");
// pojectObject = managerResponse.getString("project");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
}
Here I can get data from jsonrequest using volley but unable to do that same process using volley and gson. Is there any way to use gson?
Thank You.
Update
My JSON Response
{
"status": "200",
"msg": "Successfully",
"response": [
{
"user_id": "1",
"name": "HEMANT OJHA",
"email": "hemguna#gmail.com",
"mobile": "9584919991",
"address1": "C92, PALLAWI NAGAR BABADIYA KALAN",
"user": "admin",
"api_token": "admin"
}
]
}
Generating POJO class from JSON
// Considering your response consists of json objects & json array
// Create a POJO class for your response with the link above
{
"keyOne": 1,
"keyTwo": "Some Value",
"someArray": [{
"key": "Value"
},
{
"key": "Value"
}
]
}
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ExampleClass {
#SerializedName("keyOne")
#Expose
private int keyOne;
#SerializedName("keyTwo")
#Expose
private String keyTwo;
#SerializedName("someArray")
#Expose
private List<SomeArray> someArray = null;
public int getKeyOne() {
return keyOne;
}
public void setKeyOne(int keyOne) {
this.keyOne = keyOne;
}
public String getKeyTwo() {
return keyTwo;
}
public void setKeyTwo(String keyTwo) {
this.keyTwo = keyTwo;
}
public List<SomeArray> getSomeArray() {
return someArray;
}
public void setSomeArray(List<SomeArray> someArray) {
this.someArray = someArray;
}
}
// Parsing JSON response with GSON
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
ExampleClass resultObj = gson.fromJson(jsonObject.toString(), ExampleClass.class);
int keyOneValue = resultObj.getKeyOne() // First JSON Object
// Getting String value
String keyTwoValue = resultObj.getKeyTwo() // Second JSON Object
List<SomeArray> yourJSONArray = resultObj.getSomeArray() // Getting JSON Array contents
// Depending on JSON response that you've updated in your question
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
ExampleClass resultObj = gson.fromJson(jsonObject.toString(),ExampleClass.class);
String status = resultObj.getStatus();
String msg = resultObj.getMsg();
List<Response> responseList = resultObj.getResponse();
The best way to use for entire app is create a Utils class and use it for conversion.
GsonUtils.java
// This Class is useful for mapping Json into Java Objects and vice versa.
public class GsonUtils {
private static final Gson gson = new Gson();
// This will Convert Java Objects into JSON String...
public static String toGson(Object object) {
return gson.toJson(object);
}
// Gives Java Objects from JSON
public static <T> T fromGson(String json, Class<T> type) {
return gson.fromJson(json, type);
}
public static JsonArray fromGson(String json) {
return new JsonParser().parse(json).getAsJsonArray();
}
}
Now convert any json to and from POJO via,
POJO pojoObj = GsonUtils.toGson(POJO.class);
Try this
JSON response
String str = new Gson().toJson(response)

convert an json array to a POJO?(code wrkng on single array) [duplicate]

This question already has an answer here:
Json Array to Pojo
(1 answer)
Closed 4 years ago.
Following is the array of the json object
[
{
"name": " hh",
"place": "usa",
"isPres": false,
"id": {
"lId": {
"id1": "40",
"level1": "tte"
},
"space": "ua"
},
"isempty": null,
"isspace": true
},
{
"name": " GE",
"place": "guinea",
"isPres": true,
"id": {
"lId": {
"id1": "30",
"level1": "Le"
},
"space": "ma"
},
"isempty": null,
"isspace": false
}
]
I tried the below code to convert the JSON array to POJO
public class JsonToPojo {
public static void main(String[] args) {
String packageName="com.vogella.maven.quickstart";
File inputJson= new File("C:/projects/quickstart/input.json");
File outputPojoDirectory=new File("."+File.separator+"convertedPojo");
outputPojoDirectory.mkdirs();
try {
new JsonToPojo().convert2JSON(inputJson.toURI().toURL(), outputPojoDirectory, packageName, inputJson.getName().replace(".json", ""));
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Encountered issue while converting to pojo: "+e.getMessage());
e.printStackTrace();
}
}
public void convert2JSON(URL inputJson, File outputPojoDirectory, String packageName, String className) throws IOException{
JCodeModel codeModel = new JCodeModel();
URL source = inputJson;
GenerationConfig config = new DefaultGenerationConfig() {
#Override
public boolean isGenerateBuilders() { // set config option by overriding method
return true;
}
public SourceType getSourceType(){
return SourceType.JSON;
}
};
SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator());
mapper.generate(codeModel, className, packageName, source);
codeModel.build(outputPojoDirectory);
}
}
but the problem is i am getting the java pojo class only for one object of the array and not for the two objects
i want the result for both the arrays
Just a suggestion :: If you are using eclipse you can use https://marketplace.eclipse.org/content/jsonizer
plugin to create your pojo automatically from Sample JSON
and then in your java code, you can use Jackson mapper
ObjectMapper mapper = new ObjectMapper();
String jsonInString = "{'name' : 'mkyong'}";
//JSON from String to Object
User user = mapper.readValue(jsonInString, User.class);

GSON deserialize/serialize hierarchy class

I have a java app that send json content to my server (c++). I my server i receive the json, do the parse, the validation, etc and send back the response with json too.
I have one request in my java app that have this json body (example):
{
"a": "a",
"b": "b",
"searchMethod": {
"searchByUser": {
"userId": "userId"
}
}
}
But for the same command i can have other searchMethod:
{
"a": "a",
"b": "b",
"searchMethod": {
"searchByEmail": {
"email": "user#user.com"
}
}
}
So, when the user do the request we can send to my server one of this two different json bodys. I never know what searchMethod we send. This part (check what searchMethod the user send, etc), i do in my c++ server when i receive the json. So in my java app i only need to use the gson to send a searchMethod object with their content.
This my class to do the request:
public class RequestExample implements SerializableJSON
{
public String a;
public String b;
public RequestExample(String a, b)
{
this.a = a;
this.b = b;
}
public static RequestExample fromStringJson(String data)
{
try
{
Gson gson = new Gson();
return gson.fromJson(data, RequestExample.class);
}
catch(Exception e)
{
return null;
}
}
public static RequestExample fromBytesJson(byte[] data)
{
if (data == null) return null;
try
{
String str = new String(data, "utf-8");
return fromStringJson(str);
}
catch (Exception e)
{
return null;
}
}
#Override
public String toJsonString()
{
try
{
Gson gson = new Gson();
return gson.toJson(this);
}
catch(Exception e)
{
return null;
}
}
#Override
public byte[] toJsonBytes()
{
try
{
return this.toJsonString().getBytes("utf-8");
}
catch (Exception e)
{
return null;
}
}
}
I already implement the fields a and b because its always the same in this request. In this class the fromStringJson(String data) receive the data string field that contain all json that the user try to send. In this function i use the gson.fromJson to convert this string to a json object type of my RequestExample class.
So the main question is: How to adapt my RequestExample class to convert the string to a json object regardless of the type of searchMethod. Like i said in my java app i dont need to know how seachMethod the user choose. In my server yes, but this part i already implement. So for now, i only need to send the request to my server.
If you don't use field searchMethod, you can implement it like a Map
private Map<String, Object> searchMethod = new HashMap<>();
or
private Map<String, Map<String,Object>> searchMethod = new HashMap<>();
or
private Map<String, Map<String,String>> searchMethod = new HashMap<>();

can I set json to be pretty print only in some attributes?

I have a json with many attributes.
I want some of them to be inline. Meaning with no new break lines.
Here is my code today:
private String serializeToJson(T item) {
String json;
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
try {
json = ow.writeValueAsString(item);
} catch (IOException e) {
e.printStackTrace();
json = "";
}
return json;
}
how can I set it to be not "pretty print" for attribute path like this { "path" : { "segmentId" : 31788674, "nodeId" : 26161441, "x" : -74.236605 ...
I serialized this specific property to inline json string separately.
public ResultUiShort(ResultLong result) {
this.path = stringUtils.toInlineJson(result.path);
...
}
and
public <T> String toInlineJson(T item) {
String json;
ObjectWriter ow = new ObjectMapper().writer();
try {
json = ow.writeValueAsString(item);
} catch (IOException e) {
e.printStackTrace();
json = "";
}
return json;
}

parsing json file error whith jackon-mapper

I want parse this json structure
I inspierer this tutorial [how parse json file with jackson in android][http://www.tutos-android.com/parsing-json-jackson-android]
"Categorie": [
{
"typecategorie" : "Country",
"valeurcategorie": ["Afghanistan","Albania","Zambia","Zimbabwe"]
},
{
"typecategorie": "Year",
"valeurcategorie": ["1911","1912","1913","1960","1961","1962","1963",,"2054"]
},
{
"typecategorie": "Number",
"valeurcategorie": ["1","2","3","4","5","6","7","8","9","10","11"]
}]
I use this class
public class Categorie {
private String typecategorie;
private List<String> valeurcategorie;
public Categorie(){
super();
this.typecategorie = "";
this.valeurcategorie = new ArrayList<String>();
}
public Categorie(String typecategorie,ArrayList<String> valeurcategorie ){
super();
this.typecategorie = typecategorie;
this.valeurcategorie.addAll(valeurcategorie);
}
public List<String> getValCategorie(){
return this.valeurcategorie;
}
public String gettypecategorie(){
return typecategorie;
}
public void settypecategorie(String typecategorie){
this.typecategorie = typecategorie;
}
}
and this code for load my object
public void LoadJson(String fileName) {
try {
LoadFile(fileName);
// InputStream inputStream = urlConnection.getInputStream();
jp = jsonFactory.createJsonParser(jsonFile);
categories = objectMapper.readValue(jp, Categories.class);
categorieList = categories.get("categorie");
} catch (JsonParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
but I get this error code
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "valeurcategorie" (Class fr.lilperso.worldcupquizz.Categorie), not marked as ignorable
at [Source: /mnt/sdcard/worldCupQuizz/categorie.json; line: 5, column: 24] (through reference chain: fr.lilperso.worldcupquizz.Categorie["valeurcategorie"])
You need a setter for valeurcategorie. Add this to your Categories class:
public void setValeurcategorie(List<String> valeurcategorie) {
this.valeurcategorie = valeurcategorie;
}
You are trying to deserialize a list/array as a single object with
categories = objectMapper.readValue(jp, Categories.class);
Instead of above Categories.class, you must use Categories[].class if you are using an array or the TypeReference for list. See
How to use Jackson to deserialise an array of objects

Categories