[英]Convert JSON to a single line String and vice versa
我想将 JSON 转换为字符串字段以保存到数据库中,然后再次将其转换回 JSON。
前任。 下面是 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"}]}
]
}
我想将其转换为字符串字段“storedInput”,以便将其保存到数据库中,理想情况下只保存 JSON 数据。 当我将它发回给用户时,我还想将它转换回 JSON。
下面是我用来将其转换为分隔字符串的转换策略。
“Albert-GE-20&40#Gert-LE-26#John-$-$#Johnah Doe-LP-40”
但我不认为这是最好的策略,因为将其转换回来变得非常复杂。
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()) + "-" + "$";
}
}
编辑:
使用 JDK 15
文本块:文本块以“””(三个双引号)开头,后跟可选的空格和换行符。
请在下面找到将 json 转换为字符串的解决方案,反之亦然,它可能会对您有所帮助。
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"}]}
]
}
我建议您将学生存储在一个表中,其中包含 JSON 中的每个属性的列。 我不熟悉 Spring,但我使用的其他 web 框架能够从数据库中获取一行并以您想要的方式将其序列化为 JSON。 他们还可以将 JSON 作为单独的列而不是单个字符串放入数据库。
图书馆Josson有这个能力。
https://github.com/octomix/josson
编码
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(
"students@.concatFree(name,'-',code,'-',marks.mark.join('&')).@join('#')");
System.out.println(encoded.toPrettyString());
Output
"Albert-GE-20&40#Gert-LE-26#John--#John Doe-LP-40"
解码
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"
} ]
} ]
}
使用 JDK 17:
除了 Java 8 之外,我已经使用一些最新的 java 功能实现了以下代码。
java 14 中的记录:从 JDK 14 开始,我们可以用记录替换我们的数据类。 记录是不可变的类,只需要字段的类型和名称。 我们不需要创建构造函数、getter、setter、覆盖 toString() 方法、覆盖 hashcode 和 equals 方法。
java 15 中的文本块:文本块以“””(三个双引号)开头,后跟可选的空格和换行符。
下面的代码将为您提供要以字符串形式存储在数据库中的模式。 我希望这能解决您的疑问。
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"}]}]}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.