如何在java中模板化JSON

问题描述 投票:0回答:6

我的用例是我有一个 json 文件,但我只需将其中的几个共享给客户端。 例如:考虑源 json 文件,如下所示。

{
    "name": "XYZ",
    "age": 24,
    "education": {
        "college": "ppppp",
        "study": "b.tech",
        "grade": 6.8
    },
    "friends": ["kkkk",
    "bbbbbbbbbbb",
    "jjjjjj"],
    "dob":"01-08-1990"
}

对于客户 1,我必须分享以下输出

{
    "personalInfo": {
        "name": "XYZ",
        "age": 24,
        "friendsNames": ["kkkk","bbbbbbbbbbb","jjjjjj"]
    },
    "educationalInfo": {
        "college": "ppppp",
        "study": "b.tech",
        "grade": 6.8
    }
}

对于客户端 2,我必须分享以下输出

{
    "personalInformation": {
        "nameOfEmployee": "XYZ",
        "ageOfEmployee": 24
    },
    "educationalInformation": {
        "college": "ppppp",
        "study": "b.tech"
    }
}

对于其他客户端,用例也是相同的,我必须跳过一些键并为键指定不同的名称。如何通过某种配置动态地执行此操作。我使用 jsonPath 来实现此目的,但从 json 对象中删除几个键很困难。任何建议都可以感激。

java json templates configuration
6个回答
4
投票

使用JSON Path库,例如JayWay

那么用于转换源 JSON 的 2 个模板将是:

  • 客户1:

    {
        "personalInfo": {
            "name": "$.name",
            "age": "$.age",
            "friendsNames": "$.friends"
        },
        "educationalInfo": "$.education"
    }
    
  • 客户2:

    {
        "personalInformation": {
            "nameOfEmployee": "$.name",
            "ageOfEmployee": "$.age"
        },
        "educationalInformation": {
            "college": "$.education.college",
            "study": "$.education.study"
        }
    }
    

你需要实现的是通过JayWay的递归模板遍历

MapFunction
:

{
    ReadContext source = JsonPath.parse(...);
    MapFunction mapper = mapFunction(source);

    WriteContext template1 = JsonPath.parse(...);
    WriteContext template2 = JsonPath.parse(...);

    String client1 = template1.map("*", mapper).jsonString();
    String client2 = template2.map("*", mapper).jsonString();
}

MapFunction mapFunction(ReadContext source) {
    return (templateNode, __) -> switch (templateNode) {
        case Map map -> recurse(map, mapFunction(source));
        case List list -> recurse(list, mapFunction(source));
        case String path -> source.read(path);
    };
}

<T, R> R recurse(T templateNode, MapFunction mapper) {
    return JsonPath.parse(templateNode).map("*", mapper).read("$");
}

(可选)如果您还需要转换可变长度列表的每个元素,请为每个元素使用相同的子模板,扩展

case List list
mapFunction()
分支以支持如下模板语法:

{
    "targetProperty": [ "$.source.path.to.an.array", {
        ... element template ...
    } ]
}

例如像这样的模板:

{
    "friends": [ "$.friends[?(@ =~ /.{5,}/)]", {
        "name": "@",
        "since": "$.dob"
    } ]
}

会导致:

{
    "friends": [ {
        "name": "bbbbbbbbbbb",
        "since": "01-08-1990"
    }, {
        "name": "jjjjjj",
        "since": "01-08-1990"
    } ]
}

3
投票

您可以使用 Jackson 来序列化和反序列化 json。我建议您创建代表您的客户数据的单独的类。

我向您展示了如何反序列化数据并将其映射到客户端 json 的示例。

您可以从 http://www.jsonschema2pojo.org/ 获取一些帮助来为客户端 2 生成相应的类,以将 json 映射到 pojo。

这是代码:

public class Main {
    public static void main(String[] args) throws ParseException, ParserConfigurationException, IOException, SAXException {

        ObjectMapper mapper = new ObjectMapper();

        Root root = mapper.readValue(new File("test.json"), Root.class);

        Client1 c1 = new Client1();
        PersonalInfo personalInfo1 = new PersonalInfo();
        personalInfo1.setAge(root.getAge());
        personalInfo1.setFriendsNames(root.getFriends());
        personalInfo1.setName(root.getName());

        EducationalInfo educationalInfo1 = new EducationalInfo();
        educationalInfo1.setCollege(root.getEducation().getCollege());
        educationalInfo1.setGrade(root.getEducation().getGrade());
        educationalInfo1.setStudy(root.getEducation().getStudy());

        c1.setPersonalInfo(personalInfo1);
        c1.setEducationalInfo(educationalInfo1);

        mapper.writeValue(new File("client1.json"), c1);
    }
}

test.json 文件内部:

{
  "name": "XYZ",
  "age": 24,
  "education": {
    "college": "ppppp",
    "study": "b.tech",
    "grade": 6.8
  },
  "friends": [
    "kkkk",
    "bbbbbbbbbbb",
    "jjjjjj"
  ],
  "dob": "01-08-1990"
}

client1.json 文件内部:

{
  "personalInfo": {
    "name": "XYZ",
    "age": 24,
    "friendsNames": [
      "kkkk",
      "bbbbbbbbbbb",
      "jjjjjj"
    ]
  },
  "educationalInfo": {
    "college": "ppppp",
    "study": "b.tech",
    "grade": 6.8
  }
}

这是代表您的 json 数据的类:

class Education {
    private String college;
    private String study;
    private float grade;

    public String getCollege() {
        return college;
    }

    public void setCollege(String college) {
        this.college = college;
    }

    public String getStudy() {
        return study;
    }

    public void setStudy(String study) {
        this.study = study;
    }

    public float getGrade() {
        return grade;
    }

    public void setGrade(float grade) {
        this.grade = grade;
    }
}

// root of your base json data
class Root {

    private String name;
    private int age;
    private Education education;
    private List<String> friends;
    private String dob;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Education getEducation() {
        return education;
    }

    public void setEducation(Education education) {
        this.education = education;
    }

    public List<String> getFriends() {
        return friends;
    }

    public void setFriends(List<String> friends) {
        this.friends = friends;
    }

    public String getDob() {
        return dob;
    }

    public void setDob(String dob) {
        this.dob = dob;
    }
}

class EducationalInfo {

    private String college;
    private String study;
    private float grade;

    public String getCollege() {
        return college;
    }

    public void setCollege(String college) {
        this.college = college;
    }

    public String getStudy() {
        return study;
    }

    public void setStudy(String study) {
        this.study = study;
    }

    public float getGrade() {
        return grade;
    }

    public void setGrade(float grade) {
        this.grade = grade;
    }
}

// class which represents client 1 json data
class Client1 {

    private PersonalInfo personalInfo;
    private EducationalInfo educationalInfo;

    public PersonalInfo getPersonalInfo() {
        return personalInfo;
    }

    public void setPersonalInfo(PersonalInfo personalInfo) {
        this.personalInfo = personalInfo;
    }

    public EducationalInfo getEducationalInfo() {
        return educationalInfo;
    }

    public void setEducationalInfo(EducationalInfo educationalInfo) {
        this.educationalInfo = educationalInfo;
    }
}

class PersonalInfo {

    private String name;
    private int age;
    private List<String> friendsNames = null;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getFriendsNames() {
        return friendsNames;
    }

    public void setFriendsNames(List<String> friendsNames) {
        this.friendsNames = friendsNames;
    }
}

0
投票

将其转换为 XML 然后创建一些 XSLT 怎么样?它可能更易读且更干净。


0
投票

我将 Java 中的完整工作示例推送到带有库(lombok 和 jackson)的 GIT 模板 json 映射到对象,对象映射到不同客户端的 json。


0
投票

您的工作是将多级 JSON 数据输出为多种 JSON 格式。 JSONPath 可以做到这一点,但是过程很麻烦。

一个简单的替代方法是使用 SPL。 SPL 是一个Java 开源包。您只需要三行代码即可完成工作:

enter image description here

SPL提供了可供Java调用的JDBC驱动程序。只需将上述 SPL 脚本存储为 jsonparse.splx 并在调用存储过程时在 Java 应用程序中调用它即可:

…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call jsonparse()");
st.execute();
…

0
投票

Java 没有内置出色的模板。

但是如果你想快速创建一个肮脏的 JSON 模板,你可以在其中替换一些值——尤其是在没有所有丑陋的引号转义的情况下:

{“键”:“值”}

您可以使用单引号和字符串替换:

{'key':'VALUE'}.replace("'", """).replace("VALUE", 42)

一些注意事项:

如果任何现有键或值具有单引号(例如 O'malley),这将会中断。

它不会用数字、布尔值或 null 替换字符串

它本身不能插入嵌套数组或对象(例如 [] {}),而不是作为字符串。

但是只要做一点额外的工作,您就可以实现 80/20 规则。之后,您可能想要研究解析或生成 - 但到那时您就不再需要快速模板了。

© www.soinside.com 2019 - 2024. All rights reserved.