简体   繁体   English

将 JSON 转换为单行字符串,反之亦然

[英]Convert JSON to a single line String and vice versa

I want to convert a JSON into a string field to save into database and again convert it back to JSON.我想将 JSON 转换为字符串字段以保存到数据库中,然后再次将其转换回 JSON。

Ex.前任。 below is structure of 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"}]}
]
}

I want to convert this into a String field, "storedInput", so that i can save it into database, ideally saving only the JSON data.我想将其转换为字符串字段“storedInput”,以便将其保存到数据库中,理想情况下只保存 JSON 数据。 I also want to convert it back to the JSON when I send it back to the user.当我将它发回给用户时,我还想将它转换回 JSON。

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" “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:编辑:

  1. I do not have access to make any changes to the table structure.我无权对表结构进行任何更改。
  2. I cannot simply store the entire JSON, ex.我不能简单地存储整个 JSON,例如。 using Jackson Object Mapper, as there are space constraints, ideally i just want to store the value and convert it back.使用 Jackson Object 映射器,因为有空间限制,理想情况下我只想存储值并将其转换回来。

Using JDK 15使用 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.请在下面找到将 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: 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"}]}
    ]
    }

I suggest you store the students in a table with a column for each attribute from the JSON.我建议您将学生存储在一个表中,其中包含 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.我不熟悉 Spring,但我使用的其他 web 框架能够从数据库中获取一行并以您想要的方式将其序列化为 JSON。 They can also take JSON and put it into the database as individual columns rather than an single string.他们还可以将 JSON 作为单独的列而不是单个字符串放入数据库。

Library Josson has the capability.图书馆Josson有这个能力。

https://github.com/octomix/josson 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(
    "students@.concatFree(name,'-',code,'-',marks.mark.join('&')).@join('#')");
System.out.println(encoded.toPrettyString());

Output 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 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"
    } ]
  } ]
}

Using JDK 17:使用 JDK 17:

I have implemented the below code using some of the latest java features apart from Java 8.除了 Java 8 之外,我已经使用一些最新的 java 功能实现了以下代码。

Records in java 14: As of JDK 14, we can replace our data classes with records. java 14 中的记录:从 JDK 14 开始,我们可以用记录替换我们的数据类。 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.我们不需要创建构造函数、getter、setter、覆盖 toString() 方法、覆盖 hashcode 和 equals 方法。

Text Blocks in java 15: Text blocks start with a “”” (three double-quote marks) followed by optional whitespaces and a newline. java 15 中的文本块:文本块以“””(三个双引号)开头,后跟可选的空格和换行符。

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: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM