Search code examples
javaspringhttphttp-getjsonconvert

Json to other Java object convertion


as in the title, I need to convert the JSON file to a java object. I'm looking for a Spring or Java solution for this problem.

Here is my controller class (it will be refactored later)

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;

    }
}

Example JSON reponse:

[
  {
    "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

I'd like to convert it to such a class:

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

Do you know how can I do that? Im looking for the most optimal way to do this. Thanks for your answers. Btw http client works good at this moment but only for String response. I tried to something like

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

But it didn't work.


Solution

  • I would suggest creating a POJO for your JSON data if you aware of the fields that you would receive in JSON, you can take help from http://www.jsonschema2pojo.org/

    And Rest as follows

    Example.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>();
    
    }
    

    Owner.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> additionalProperties = new HashMap<String, Object>();
    

    }

    RepositoryDetailsDTO.java

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

    Main Class

    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)));
        }
    }
    

    Output:

    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, description=This your first repo!, clone_url=https://github.com/octocat/Hello-World.git, stars=null, createdAt=null)