如何使用Jackson创建嵌套的JSON对象

huangapple go评论78阅读模式
英文:

How to create nested json objects with jackson

问题

使用Hibernate从数据库查询用户记录代码如下

String hql = "SELECT U FROM User U";
List<User> users = this.em.createQuery(hql).getResultList();

我要如何将返回的数据转换成以下格式的JSON

如果没有找到用户我希望我的JSON看起来如下所示

在创建JSON数据之前我想对检索到的数据进行一些操作因此我希望避免直接传递列表如下所示

String data = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(users);
英文:

I am using hibernate to query records of users from my db as shown:

String hql = &quot;SELECT U FROM User U&quot;;
List&lt;User&gt; users = this.em.createQuery(hql).getResultList();

How do I convert the returned data into json as shown in the format below:

如何使用Jackson创建嵌套的JSON对象

If no users are found I want my json to look as shown below:

如何使用Jackson创建嵌套的JSON对象

I want to do some manipulation on the retrieved data before creating the json data. Therefore I want to avoid passing the list directly as shown below:

 String data = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(users);

答案1

得分: 0

你可以逐步构建 JSON:

首先,我建议在 User 类中创建一个方法,该方法将用户的姓名和电子邮件以 JSON 形式返回。

public class User {

    ...
 
    public String getJsonUserEmail() {
        return "{\"name\": \"" + this.getName() + "\", " +
               "\"email\": \"" + this.getEmail() + "\"}";
    }

    ...

}

然后将所有用户转换为 JSON,并构建最终的 JSON。

public static void main(String[] args) {
    String finalJson = "{";

    if (!users.isEmpty()) {
        finalJson += "\"usersFound\": true, ";

        // 将每个用户转换为 JSON
        List<String> usersJson = users.stream()
                                      .map(e -> e.getJsonUserEmail())
                                      .collect(Collectors.toList());

        // 连接所有 JSON
        String usersJsonJoin = String.join(", ", usersJson);

        finalJson += "\"users\": [" + usersJsonJoin + "]";
    } else {
        finalJson += "\"usersFound\": false, ";
        finalJson += "\"msg\": \"No users found\"";
    }

    finalJson += "}";
}
英文:

You can simply build json step by step:

At first step I would recommend to create a method in User class which gives name and email of user as json.

public class User{

    ...
 
    public String getJsonUserEmail(){

        return &quot;{\&quot;name\&quot;: \&quot;&quot; + this.getName() + &quot;\&quot;, &quot; +
                &quot;\&quot;email\&quot;: \&quot;&quot; + this.getEmail() + &quot;\&quot;}&quot;

    }

    ...

}


Than transform all users to json and build the last json.

public static void main(String[] args) {

	String finalJson = &quot;{&quot;;

	if(!users.isEmpty()){

		finalJson += &quot;\&quot;usersFound\&quot;: true, &quot;;
                
        //transform every user to json
        //{&quot;name&quot;: &quot;name1&quot;, &quot;email&quot;: &quot;email1&quot;}
	    List&lt;String&gt; usersJson = users.stream()
									  .map(e -&gt; e.getJsonUserEmail())
									  .collect(Collectors.toList());

        //join all jsons
        //{&quot;name&quot;: &quot;name1&quot;, &quot;email&quot;: &quot;email1&quot;}, {&quot;name&quot;: &quot;name2&quot;, &quot;email&quot;: &quot;email2&quot;}, ...
		String usersJsonJoin = String.join(&quot;, &quot;, usersJson);

		finalJson += &quot;\&quot;users\&quot;: [&quot; + usersJsonJoin + &quot;]&quot;;

	}else{

		finalJson += &quot;\&quot;usersFound\&quot;: false, &quot;;
		finalJson += &quot;\&quot;msg\&quot;: \&quot;No users found\&quot;&quot;;

	}

	finalJson += &quot;}&quot;;

}

答案2

得分: 0

使用Jackson库时,您应该实现一个简单的DTO对象,其中包含一个User / UserDto列表,以及一个带有自定义msg属性的空列表存根,然后根据可用结果创建适当的实例。

此外,您可以使用@JsonPropertyOrder注解设置生成的JSON中属性的顺序。

public class UserDto {
    private final String name;
    private final String email;

    public UserDto(String name, String email) {
        this.name = name;
        this.email = email;
    }
    public String getName() { return this.name; }
    public String getEmail() { return this.email; }
}

@JsonPropertyOrder({ "usersFound", "users" })
public class ListUserDto {
    private final List<UserDto> users;

    public ListUserDto(List<UserDto> users) {
        this.users = users;
    }

    public List<UserDto> getUsers() {
        return new ArrayList<>(users);
    }

    @JsonProperty("usersFound")
    public boolean isUsersFound() {
        return true;
    }
}

@JsonPropertyOrder({ "usersFound", "msg" })
@JsonIgnoreProperties(value = {"users"})
public class EmptyListUserDto extends ListUserDto {
    public EmptyListUserDto() {
        super(Collections.emptyList());
    }

    public String getMsg() {
        return "No User Found";
    }

    @JsonProperty("usersFound")
    public boolean isUsersFound() {
        return false;
    }
}


// -------------
public ListUserDto buildUserListJson(List<User> users) {
//    String hql = "SELECT U FROM User U";
//    List<User> users = this.em.createQuery(hql).getResultList();

    if (null == users || users.isEmpty()) {
        return new EmptyListUserDto();
    }
    return new ListUserDto(
            users.stream()
                 .map(u -> new UserDto(u.getName(), u.getEmail()))
                 .collect(Collectors.toList())
    );
}

测试代码:

ObjectWriter writer = new ObjectMapper().writerWithDefaultPrettyPrinter();

System.out.println(writer.writeValueAsString(buildUserListJson(
    List.of(new User("jack", "jack@mail.com"), new User("john", "john@mail.com"))
)));

System.out.println("null -> " + writer.writeValueAsString(buildUserListJson(null)));

System.out.println("empty -> " + writer.writeValueAsString(buildUserListJson(Collections.emptyList())));

输出:

{
  "usersFound" : true,
  "users" : [ {
    "name" : "jack",
    "email" : "jack@mail.com"
  }, {
    "name" : "john",
    "email" : "john@mail.com"
  } ]
}
null -> {
  "usersFound" : false,
  "msg" : "No User Found"
}
empty -> {
  "usersFound" : false,
  "msg" : "No User Found"
}
英文:

If you are using Jackson library, you should implement a simple DTO object containing a list of User / UserDto, a stub for an empty list with custom msg property and then create appropriate instance depending on available results.

Also you can set the order of properties in the generated JSON using @JsonPropertyOrder annotation.

public class UserDto {
    private final String name;
    private final String email;

    public UserDto(String name, String email) {
        this.name = name;
        this.email = email;
    }
    public String getName() { return this.name; }
    public String getEmail() { return this.email; }
}

@JsonPropertyOrder({ &quot;usersFound&quot;, &quot;users&quot; })
public class ListUserDto {
    private final List&lt;UserDto&gt; users;

    public ListUserDto(List&lt;UserDto&gt; users) {
        this.users = users;
    }

    public List&lt;UserDto&gt; getUsers() {
        return new ArrayList&lt;&gt;(users);
    }

    @JsonProperty(&quot;usersFound&quot;)
    public boolean isUsersFound() {
        return true;
    }
}

@JsonPropertyOrder({ &quot;usersFound&quot;, &quot;msg&quot; })
@JsonIgnoreProperties(value = {&quot;users&quot;})
public class EmptyListUserDto extends ListUserDto {
    public EmptyListUserDto() {
        super(Collections.emptyList());
    }

    public String getMsg() {
        return &quot;No User Found&quot;;
    }

    @JsonProperty(&quot;usersFound&quot;)
    public boolean isUsersFound() {
        return false;
    }
}


// -------------
public ListUserDto buildUserListJson(List&lt;User&gt; users) {
//    String hql = &quot;SELECT U FROM User U&quot;;
//    List&lt;User&gt; users = this.em.createQuery(hql).getResultList();

    if (null == users || users.isEmpty()) {
        return new EmptyListUserDto();
    }
    return new ListUserDto(
            users.stream()
                 .map(u -&gt; new UserDto(u.getName(), u.getEmail()))
                 .collect(Collectors.toList())
    );
}

Test code:

ObjectWriter writer = new ObjectMapper().writerWithDefaultPrettyPrinter();

System.out.println(writer.writeValueAsString(buildUserListJson(
    List.of(new User(&quot;jack&quot;, &quot;jack@mail.com&quot;), new User(&quot;john&quot;, &quot;john@mail.com&quot;))
)));

System.out.println(&quot;null -&gt; &quot; + writer.writeValueAsString(buildUserListJson(null)));

System.out.println(&quot;empty -&gt; &quot; + writer.writeValueAsString(buildUserListJson(Collections.emptyList())));

Output:

{
&quot;usersFound&quot; : true,
&quot;users&quot; : [ {
&quot;name&quot; : &quot;jack&quot;,
&quot;email&quot; : &quot;jack@mail.com&quot;
}, {
&quot;name&quot; : &quot;john&quot;,
&quot;email&quot; : &quot;john@mail.com&quot;
} ]
}
null -&gt; {
&quot;usersFound&quot; : false,
&quot;msg&quot; : &quot;No User Found&quot;
}
empty -&gt; {
&quot;usersFound&quot; : false,
&quot;msg&quot; : &quot;No User Found&quot;
}

huangapple
  • 本文由 发表于 2020年9月14日 22:51:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63886742.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定