Json 到其他 Java 对象的转换

问题描述

如标题所示,我需要将 JSON 文件转换为 java 对象。我正在寻找解决此问题的 Spring 或 Java 解决方案。

这是我的控制器类(稍后会重构)

package pl.githubdetails.GithubDetails.presentation;

import org.springframework.boot.json.GsonJsonParser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pl.githubdetails.GithubDetails.applcation.RepositoryDetailsDTO;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.text.MessageFormat;

@RestController
@RequestMapping("/repositories")
public class DetailsController
{
    final String uriTemplate = "https://api.github.com/repos/{0}/{1}";

    @GetMapping(value = "/{owner}/{repositoryName}")
    RepositoryDetailsDTO getRepositoryDetails(@PathVariable String owner,@PathVariable String repositoryName) throws IOException,InterruptedException {
        RepositoryDetailsDTO repositoryDetailsDTO = new RepositoryDetailsDTO();
        String uri = MessageFormat.format(uriTemplate,owner,repositoryName);
        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .GET()
                .uri(URI.create(uri))
                .build();

        HttpResponse<String> httpResponse = httpClient.send(request,HttpResponse.BodyHandlers.ofString());
        System.out.println(httpResponse.body());
        return null;

    }
}

JSON 响应示例:

[
  {
    "id": 1296269,"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5","name": "Hello-World","full_name": "octocat/Hello-World","owner": {
      "login": "octocat","id": 1,"node_id": "MDQ6VXNlcjE=","avatar_url": "https://github.com/images/error/octocat_happy.gif","gravatar_id": "","url": "https://api.github.com/users/octocat","html_url": "https://github.com/octocat","followers_url": "https://api.github.com/users/octocat/followers","following_url": "https://api.github.com/users/octocat/following{/other_user}","gists_url": "https://api.github.com/users/octocat/gists{/gist_id}","starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}","subscriptions_url": "https://api.github.com/users/octocat/subscriptions","organizations_url": "https://api.github.com/users/octocat/orgs","repos_url": "https://api.github.com/users/octocat/repos","events_url": "https://api.github.com/users/octocat/events{/privacy}","received_events_url": "https://api.github.com/users/octocat/received_events","type": "User","site_admin": false
    },"private": false,"html_url": "https://github.com/octocat/Hello-World","description": "This your first repo!","fork": false,"url": "https://api.github.com/repos/octocat/Hello-World","archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}","assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}","blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}","branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}","collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}","comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}","commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}","compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}","contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}","contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors","deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments","downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads","events_url": "https://api.github.com/repos/octocat/Hello-World/events","forks_url": "https://api.github.com/repos/octocat/Hello-World/forks","git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}","git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}","git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}","git_url": "git:github.com/octocat/Hello-World.git","issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}","issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}","issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}","keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}","labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}","languages_url": "https://api.github.com/repos/octocat/Hello-World/languages","merges_url": "https://api.github.com/repos/octocat/Hello-World/merges","milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}","notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}","pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}","releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}","ssh_url": "git@github.com:octocat/Hello-World.git","stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers","statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}","subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers","subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription","tags_url": "https://api.github.com/repos/octocat/Hello-World/tags","teams_url": "https://api.github.com/repos/octocat/Hello-World/teams","trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}","clone_url": "https://github.com/octocat/Hello-World.git","mirror_url": "git:git.example.com/octocat/Hello-World","hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks","svn_url": "https://svn.github.com/octocat/Hello-World","homepage": "https://github.com","language": null,"forks_count": 9,"stargazers_count": 80,"watchers_count": 80,"size": 108,"default_branch": "master","open_issues_count": 0,"is_template": false,"topics": [
      "octocat","atom","electron","api"
    ],"has_issues": true,"has_projects": true,"has_wiki": true

我想把它转换成这样一个类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RepositoryDetailsDTO
{
    String full_name;
    String description;
    String cloneUrl;
    String stars;
    String createdAt;
}

你知道我该怎么做吗?我正在寻找执行此操作的最佳方法。感谢您的回答。顺便说一句,http 客户端此时运行良好,但仅适用于字符串响应。我尝试过类似

HttpResponse<RepositoryDetailsDTO> httpResponse = httpClient.send(request,HttpResponse.BodyHandlers.replacing(repositoryDetailsDTO));

但是没有用。

解决方法

如果您知道将在 JSON 中接收到的字段,我建议为您的 JSON 数据创建一个 POJO,您可以从 http://www.jsonschema2pojo.org/

获得帮助

然后休息如下

示例.java

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class Example {
    private Integer id;
    private String node_id;
    private String name;
    private String full_name;
    private Owner owner;
    @JsonProperty("private")
    private Boolean _private;
    private String html_url;
    private String description;
    private Boolean fork;
    private String url;
    private String archive_url;
    private String assignees_url;
    private String blobs_url;
    private String branches_url;
    private String collaborators_url;
    private String comments_url;
    private String commits_url;
    private String compare_url;
    private String contents_url;
    private String contributors_url;
    private String deployments_url;
    private String downloads_url;
    private String events_url;
    private String forks_url;
    private String git_commits_url;
    private String git_refs_url;
    private String git_tags_url;
    private String git_url;
    private String issue_comment_url;
    private String issue_events_url;
    private String issues_url;
    private String keys_url;
    private String labels_url;
    private String languages_url;
    private String merges_url;
    private String milestones_url;
    private String notifications_url;
    private String pulls_url;
    private String releases_url;
    private String ssh_url;
    private String stargazers_url;
    private String statuses_url;
    private String subscribers_url;
    private String subscription_url;
    private String tags_url;
    private String teams_url;
    private String trees_url;
    private String clone_url;
    private String mirror_url;
    private String hooks_url;
    private String svn_url;
    private String homepage;
    private Object language;
    private Integer forks_count;
    private Integer stargazers_count;
    private Integer watchers_count;
    private Integer size;
    private String default_branch;
    private Integer open_issues_count;
    private Boolean is_template;
    private List<String> topics = null;
    private Boolean has_issues;
    private Boolean has_projects;
    private Boolean has_wiki;
    @JsonIgnore
    private Map<String,Object> additionalProperties = new HashMap<String,Object>();

}

所有者.java

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class Owner {

@JsonProperty("login")
private String login;
@JsonProperty("id")
private Integer id;
@JsonProperty("node_id")
private String nodeId;
@JsonProperty("avatar_url")
private String avatarUrl;
@JsonProperty("gravatar_id")
private String gravatarId;
@JsonProperty("url")
private String url;
@JsonProperty("html_url")
private String htmlUrl;
@JsonProperty("followers_url")
private String followersUrl;
@JsonProperty("following_url")
private String followingUrl;
@JsonProperty("gists_url")
private String gistsUrl;
@JsonProperty("starred_url")
private String starredUrl;
@JsonProperty("subscriptions_url")
private String subscriptionsUrl;
@JsonProperty("organizations_url")
private String organizationsUrl;
@JsonProperty("repos_url")
private String reposUrl;
@JsonProperty("events_url")
private String eventsUrl;
@JsonProperty("received_events_url")
private String receivedEventsUrl;
@JsonProperty("type")
private String type;
@JsonProperty("site_admin")
private Boolean siteAdmin;
@JsonIgnore
private Map<String,Object>();

}

RepositoryDe​​tailsDTO.java

import lombok.Data;

@Data
public class RepositoryDetailsDTO {
    String full_name;
    String description;
    String clone_url;
    String stars;
    String createdAt;
}

主类

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.BeanUtils;

import java.nio.file.Files;
import java.nio.file.Paths;

public class JSONPractise {
    public static void main(String[] args) throws Exception {

        String file = "DataFile.json";
        String jsonStr = readFileAsString(file);
        ObjectMapper mapper = new ObjectMapper();
        Example example =  mapper.readValue(jsonStr,Example.class);
        RepositoryDetailsDTO repositoryDetailsDTO = new RepositoryDetailsDTO();
        BeanUtils.copyProperties(repositoryDetailsDTO,example);

        System.out.println(example.toString());
        System.out.println(repositoryDetailsDTO.toString());
    }
    public static String readFileAsString(String file)throws Exception
    {
        return new String(Files.readAllBytes(Paths.get(file)));
    }
}

输出:

Example(id=1296269,node_id=MDEwOlJlcG9zaXRvcnkxMjk2MjY5,name=Hello-World,full_name=octocat/Hello-World,owner=Owner(login=octocat,id=1,nodeId=MDQ6VXNlcjE=,avatarUrl=https://github.com/images/error/octocat_happy.gif,gravatarId=,url=https://api.github.com/users/octocat,htmlUrl=https://github.com/octocat,followersUrl=https://api.github.com/users/octocat/followers,followingUrl=https://api.github.com/users/octocat/following{/other_user},gistsUrl=https://api.github.com/users/octocat/gists{/gist_id},starredUrl=https://api.github.com/users/octocat/starred{/owner}{/repo},subscriptionsUrl=https://api.github.com/users/octocat/subscriptions,organizationsUrl=https://api.github.com/users/octocat/orgs,reposUrl=https://api.github.com/users/octocat/repos,eventsUrl=https://api.github.com/users/octocat/events{/privacy},receivedEventsUrl=https://api.github.com/users/octocat/received_events,type=User,siteAdmin=false,additionalProperties={}),_private=false,html_url=https://github.com/octocat/Hello-World,description=This your first repo!,fork=false,url=https://api.github.com/repos/octocat/Hello-World,archive_url=https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref},assignees_url=https://api.github.com/repos/octocat/Hello-World/assignees{/user},blobs_url=https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha},branches_url=https://api.github.com/repos/octocat/Hello-World/branches{/branch},collaborators_url=https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator},comments_url=https://api.github.com/repos/octocat/Hello-World/comments{/number},commits_url=https://api.github.com/repos/octocat/Hello-World/commits{/sha},compare_url=https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head},contents_url=https://api.github.com/repos/octocat/Hello-World/contents/{+path},contributors_url=https://api.github.com/repos/octocat/Hello-World/contributors,deployments_url=https://api.github.com/repos/octocat/Hello-World/deployments,downloads_url=https://api.github.com/repos/octocat/Hello-World/downloads,events_url=https://api.github.com/repos/octocat/Hello-World/events,forks_url=https://api.github.com/repos/octocat/Hello-World/forks,git_commits_url=https://api.github.com/repos/octocat/Hello-World/git/commits{/sha},git_refs_url=https://api.github.com/repos/octocat/Hello-World/git/refs{/sha},git_tags_url=https://api.github.com/repos/octocat/Hello-World/git/tags{/sha},git_url=git:github.com/octocat/Hello-World.git,issue_comment_url=https://api.github.com/repos/octocat/Hello-World/issues/comments{/number},issue_events_url=https://api.github.com/repos/octocat/Hello-World/issues/events{/number},issues_url=https://api.github.com/repos/octocat/Hello-World/issues{/number},keys_url=https://api.github.com/repos/octocat/Hello-World/keys{/key_id},labels_url=https://api.github.com/repos/octocat/Hello-World/labels{/name},languages_url=https://api.github.com/repos/octocat/Hello-World/languages,merges_url=https://api.github.com/repos/octocat/Hello-World/merges,milestones_url=https://api.github.com/repos/octocat/Hello-World/milestones{/number},notifications_url=https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating},pulls_url=https://api.github.com/repos/octocat/Hello-World/pulls{/number},releases_url=https://api.github.com/repos/octocat/Hello-World/releases{/id},ssh_url=git@github.com:octocat/Hello-World.git,stargazers_url=https://api.github.com/repos/octocat/Hello-World/stargazers,statuses_url=https://api.github.com/repos/octocat/Hello-World/statuses/{sha},subscribers_url=https://api.github.com/repos/octocat/Hello-World/subscribers,subscription_url=https://api.github.com/repos/octocat/Hello-World/subscription,tags_url=https://api.github.com/repos/octocat/Hello-World/tags,teams_url=https://api.github.com/repos/octocat/Hello-World/teams,trees_url=https://api.github.com/repos/octocat/Hello-World/git/trees{/sha},clone_url=https://github.com/octocat/Hello-World.git,mirror_url=git:git.example.com/octocat/Hello-World,hooks_url=https://api.github.com/repos/octocat/Hello-World/hooks,svn_url=https://svn.github.com/octocat/Hello-World,homepage=https://github.com,language=null,forks_count=9,stargazers_count=80,watchers_count=80,size=108,default_branch=master,open_issues_count=0,is_template=false,topics=[octocat,atom,electron,api],has_issues=true,has_projects=true,has_wiki=true,additionalProperties={})
RepositoryDetailsDTO(full_name=octocat/Hello-World,stars=null,createdAt=null)
,

问题解决了我发现了类似的东西:

repositoryDetailsDTO = new ObjectMapper()
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false)
                .readValue(httpResponse.body(),RepositoryDetailsDTO.class);

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...