簡體   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