I want to convert a JSON into a string field to save into database and again convert it back to JSON.
Ex. below is structure of JSON:
{
"students":[{
"name": "Albert",
"code":"GE",
"marks":[{"mark":"20"},{"mark":"40"}]},
{
"name": "Gert",
"code":"LE",
"marks":[{"mark":"26"}]},
{
"name": "John"
},
{
"name": "John Doe",
"code":"LP",
"marks":[{"mark":"40"}]}
]
}
I want to convert this into a String field, "storedInput", so that i can save it into database, ideally saving only the JSON data. I also want to convert it back to the JSON when I send it back to the user.
Below is the conversion strategy I used to convert it into delimited String.
"Albert-GE-20&40#Gert-LE-26#John-$-$#Johnah Doe-LP-40"
But I dont think its the best strategy as it gets extremely complicated to convert it back.
public String convertStudentList(List<Student> studentList) {
return studentList.stream().map(this::mapStudent).collect(Collectors.joining("#"));
}
public String checkData(String data) {
return Optional.ofNullable(data).isPresent() ? data : "$";
}
public String mapStudent(Student student) {
List<Marks> marks = student.getMarks();
if (marks != null) {
String mark = marks.stream().map(m -> m.getMark()).collect(Collectors.joining("&"));
return checkData(student.getName()) "-" checkData(student.getCode()) "-" mark;
} else {
return checkData(student.getName()) "-" checkData(student.getCode()) "-" "$";
}
}
Edit:
- I do not have access to make any changes to the table structure.
- I cannot simply store the entire JSON, ex. using Jackson Object Mapper, as there are space constraints, ideally i just want to store the value and convert it back.
CodePudding user response:
I suggest you store the students in a table with a column for each attribute from the JSON. I am not familiar with Spring, but other web frameworks I used are able to fetch a row from the database and seralize it to JSON in the way you want. They can also take JSON and put it into the database as individual columns rather than an single string.
CodePudding user response:
Using JDK 15
Text Blocks : Text blocks start with a “”” (three double-quote marks) followed by optional whitespaces and a newline.
Please find the solution below to convert json to string and vice-versa, it might help you in some way.
public class Test {
public static void main(String[] args) throws JsonProcessingException {
String s = """
{
"students":[{
"name": "Albert",
"code":"GE",
"marks":[{"mark":"20"},{"mark":"40"}]},
{
"name": "Gert",
"code":"LE",
"marks":[{"mark":"26"}]},
{
"name": "John"
},
{
"name": "John Doe",
"code":"LP",
"marks":[{"mark":"40"}]}
]
}
""";
//JSON TO STRING
ObjectMapper mapper = new ObjectMapper();
String s2 = mapper.writeValueAsString(s);
System.out.println("JSON TO STRING:" s2);
//STRING TO JSON
String s3 = mapper.readValue(s2, new TypeReference<>() {});
System.out.println("STRING TO JSON:" s3);
}
}
Output:
JSON TO STRING:"{\n\"students\":[{\n\"name\": \"Albert\",\n\"code\":\"GE\",\n\"marks\":[{\"mark\":\"20\"},{\"mark\":\"40\"}]},\n{\n\"name\": \"Gert\",\n\"code\":\"LE\",\n\"marks\":[{\"mark\":\"26\"}]},\n{\n\"name\": \"John\"\n},\n{\n\"name\": \"John Doe\",\n\"code\":\"LP\",\n\"marks\":[{\"mark\":\"40\"}]}\n]\n}\n"
STRING TO JSON:{
"students":[{
"name": "Albert",
"code":"GE",
"marks":[{"mark":"20"},{"mark":"40"}]},
{
"name": "Gert",
"code":"LE",
"marks":[{"mark":"26"}]},
{
"name": "John"
},
{
"name": "John Doe",
"code":"LP",
"marks":[{"mark":"40"}]}
]
}
CodePudding user response:
Library Josson has the capability.
https://github.com/octomix/josson
Encode
Josson josson = Josson.fromJsonString(
"{"
"\"students\":[{"
"\"name\": \"Albert\","
"\"code\":\"GE\","
"\"marks\":[{\"mark\":\"20\"},{\"mark\":\"40\"}]},"
"{"
"\"name\": \"Gert\","
"\"code\":\"LE\","
"\"marks\":[{\"mark\":\"26\"}]},"
"{"
"\"name\": \"John\""
"},"
"{"
"\"name\": \"John Doe\","
"\"code\":\"LP\","
"\"marks\":[{\"mark\":\"40\"}]}"
"]"
"}");
JsonNode encoded = josson.getNode(
"[email protected](name,'-',code,'-',marks.mark.join('&')).@join('#')");
System.out.println(encoded.toPrettyString());
Output
"Albert-GE-20&40#Gert-LE-26#John--#John Doe-LP-40"
Decode
Josson josson = Josson.fromJsonString(
"\"Albert-GE-20&40#Gert-LE-26#John--#Johnah Doe-LP-40\"");
JsonNode decoded = josson.getNode(
"split('#').split('-').map(name:[0],code:[1],marks:[2].split('&').map(mark:?)).toObject('students')");
System.out.println(decoded.toPrettyString());
Output
{
"students" : [ {
"name" : "Albert",
"code" : "GE",
"marks" : [ {
"mark" : "20"
}, {
"mark" : "40"
} ]
}, {
"name" : "Gert",
"code" : "LE",
"marks" : [ {
"mark" : "26"
} ]
}, {
"name" : "John"
}, {
"name" : "Johnah Doe",
"code" : "LP",
"marks" : [ {
"mark" : "40"
} ]
} ]
}
CodePudding user response:
Using JDK 17:
I have implemented the below code using some of the latest java features apart from Java 8.
Records in java 14 : As of JDK 14, we can replace our data classes with records. Records are immutable classes that require only the type and name of fields. We do not need to create constructor, getters, setters, override toString() methods, override hashcode and equals methods.
Text Blocks in java 15: Text blocks start with a “”” (three double-quote marks) followed by optional whitespaces and a newline.
The below code will give you the pattern that you want to store in the database in the form of a string. I hope this will solve your query.
public class JsonTest {
public static void main(String[] args) throws JsonProcessingException {
//Converting json to formatted String
record Marks(String mark){}
record Student(String name, String code, List<Marks> marks){}
record Response(List<Student> students){}
String input = """
{
"students":[{
"name": "Albert",
"code":"GE",
"marks":[{"mark":"20"},{"mark":"40"}]},
{
"name": "Gert",
"code":"LE",
"marks":[{"mark":"26"}]},
{
"name": "John"
},
{
"name": "John Doe",
"code":"LP",
"marks":[{"mark":"40"}]}
]
}
""";
ObjectMapper mapper = new ObjectMapper();
Response studentData = mapper.readValue(input, new TypeReference<>() {});
StringBuilder sb = new StringBuilder();
studentData.students().forEach(x -> {
sb.append(x.name() "-");
sb.append(x.code()!= null ? x.code() : "$");
sb.append("-");
sb.append(x.marks()!= null ? x.marks().stream().filter(y -> y.mark()!=null).map(Marks::mark).collect(Collectors.joining("&")) : "$");
sb.append("#");
});
System.out.println(sb);
}
//Converting formatted String to original json
List<Student> students = new ArrayList<>();
Arrays.asList(sb.toString().split("#")).forEach(student -> {
String[] splitArr1 = student.split("-");
String[] splitArr2 = splitArr1[2].split("&");
String name = splitArr1[0];
String code = splitArr1[1].contains("$")?null:splitArr1[1];
List<Marks> marks = Arrays.stream(splitArr2).filter(y -> !y.contains("$")).map(Marks::new).toList();
Student s = new Student(name,code,marks);
students.add(s);
});
Response out = new Response(students);
String backToJson = mapper.writeValueAsString(out);
System.out.println(backToJson);
}
}
Output:
//Converting json to formatted String
Albert-GE-20&40#Gert-LE-26#John-$-$#John Doe-LP-40#
//Converting formatted String to original json
{"students":[{"name":"Albert","code":"GE","marks":[{"mark":"20"},{"mark":"40"}]},{"name":"Gert","code":"LE","marks":[{"mark":"26"}]},{"name":"John","code":null,"marks":[]},{"name":"John Doe","code":"LP","marks":[{"mark":"40"}]}]}