【问题标题】:How to create nested json objects with jackson如何使用杰克逊创建嵌套的 json 对象
【发布时间】:2020-09-14 14:51:46
【问题描述】:

我正在使用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);

【问题讨论】:

  • 如果usersFoundfalse,json 的外观如何?
  • @KunLun no users found 回复已添加
  • 如果usersFound=false,为什么不返回空的用户列表?我的意思是 usersFound 在响应中是多余的
  • 你为什么不试试 DTO 呢? en.wikipedia.org/wiki/Data_transfer_object
  • 另一种解决方案,一种更简单的方法。你可以试试 toString @Override public String toString() { return "{" + "\"name\":\"" + name + '\"' + ", \"email\":\"" + email + ' \"' + '}'; }

标签: java json hibernate jackson


【解决方案1】:

如果您使用的是 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"
}

【讨论】:

    【解决方案2】:

    你可以简单的一步一步构建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, ";
                    
            //transform every user to json
            //{"name": "name1", "email": "email1"}
            List<String> usersJson = users.stream()
                                          .map(e -> e.getJsonUserEmail())
                                          .collect(Collectors.toList());
    
            //join all jsons
            //{"name": "name1", "email": "email1"}, {"name": "name2", "email": "email2"}, ...
            String usersJsonJoin = String.join(", ", usersJson);
    
            finalJson += "\"users\": [" + usersJsonJoin + "]";
    
        }else{
    
            finalJson += "\"usersFound\": false, ";
            finalJson += "\"msg\": \"No users found\"";
    
        }
    
        finalJson += "}";
    
    }
    

    【讨论】:

    • 我建议在用户对象中写一个方法
    • @Tea,我是这么想的,但问题是没有提到User类的结构,所以我想除了nameemail之外还有多个字段。跨度>
    猜你喜欢
    • 1970-01-01
    • 2016-12-07
    • 2013-06-03
    • 1970-01-01
    • 2016-01-14
    • 2019-11-15
    • 2018-02-16
    • 1970-01-01
    • 2018-12-10
    相关资源
    最近更新 更多