繁体   English   中英

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

[英]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()) + "-" + "$";
    }
}

编辑:

  1. 我无权对表结构进行任何更改。
  2. 我不能简单地存储整个 JSON,例如。 使用 Jackson Object 映射器,因为有空间限制,理想情况下我只想存储值并将其转换回来。

使用 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.

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