1

I'm trying to get the first 5 articles from this API: https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=19acc3a371d145ecb37a093f9985ea21

My code works perfectly for now, but it parses all 10 articles of NewsAPI.

The code is:

public News parse() {

    return restTemplate.getForObject
                    ("https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=19acc3a371d145ecb37a093f9985ea21", News.class);

    }
}

and the result is:

{
    "totalResults": 10,
    "articles": [
        {
            "source": {
                "id": "bbc-news",
                "name": "BBC News"
            },
            "author": "BBC News",
            "title": "Measles returns to four European nations, WHO says",
            "url": "http://www.bbc.co.uk/news/health-49507253"
        },
    etc......

Of course, i created the classes that describe Article, Source and News. News has a List of Article.

I just want to parse the first five articles and save them into a List. I know I have to use a For cycle, but how can i do that? I tried with this code:

public News parseFive() {
    List<Article> articleList = null;

    for(int i = 0; i<5; i++) {
        articleList = Arrays.asList(
        new Article(restTemplate.getForObject
                                ("https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=19acc3a371d145ecb37a093f9985ea21", Article.class)));
    }
    News news = new News();
    news.setArticles(articleList);
    return news;
}

The News class is:

public class News {

    private int totalResults;

    private List<Article> articles;

    public News() {

    }

    public int getTotalResults() {
        return totalResults;
    }

    public void setTotalResults(int totalResults) {
        this.totalResults = totalResults;
    }

    public List<Article> getArticles() {
        return articles;
    }

    public void setArticles() {
        this.articles = articles;
    }
}

and the result is:

{
    "totalResults": 0,
    "articles": [
        {
            "source": null,
            "author": null,
            "title": null,
            "url": null
        }
    ]
}

Where is the problem? Maybe because the first class who finds is not Article but is News? Thanks everyone for the effort.

1 Answers1

0

When you are using RestTemplate.getForObject you are technically parsing the whole response: Spring reads all the bytes and uses JSON parser (Jackson) to create an object. Your for loop, which is covered later, only filters out elements past 5th. If you really want to parse only first 5 articles, you should consider using Jackson Streaming API. It is quiet problematically to use with RestTemplate, read this answer for more info.

Now let's try to fix your parseFive.

First, create a class to capture whole response:

public class Response {
    private String status;
    private Integer totalResults;
    private List<Artice> articles;

    // Getters & Setters
}

Now, get first five articles:

public News parseFive() {
    final Response response = restTemplate
        .getForObject("https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=19acc3a371d145ecb37a093f9985ea21", Response.class);
    final News news = new News();

    news.setArticles(response.articles.stream().limit(5).collect(Collectors.toList());

    return news;
}

You have not provided your News class, probably it is the same as response. Then, the code may look like:

public News parseFive() {
    final News news = restTemplate
        .getForObject("https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=19acc3a371d145ecb37a093f9985ea21", Response.class);

    news.setArticles(news.articles.stream().limit(5).collect(Collectors.toList());

    return news;
}

madhead
  • 31,729
  • 16
  • 153
  • 201
  • I already have the class you created and called Response, it's name is News... It's the same, but without the Status field. Do i have to put status in the class to make it work? Anyway, i'll try to do the ParseFive <3 thanks for the effort, i'll let you know if it works! – Marco Frag Delle Monache Aug 29 '19 at 10:02
  • yes, sorry for not providing the news.class..... my bad. and thanks for the correction <3 – Marco Frag Delle Monache Aug 29 '19 at 10:06
  • WORKING! everything ok <3 but now there's a problem.... the totalResults is equal to 10 because it parses the value from the json.... how can i avoid parsing the totalResults and make it counting the parsed articles? thanks anyway for the solution <3 – Marco Frag Delle Monache Aug 29 '19 at 10:11
  • Just reassign it to the required value like: `news.setTotalResults(5);` or better `news.setTotalResults(news.articles.size());` – madhead Aug 29 '19 at 10:12
  • 1
    ok nothing, i just put the setTotalResults(counter) where counter is used in the limit method and is equal to 5. i really thank you for the effort! working perfectly! – Marco Frag Delle Monache Aug 29 '19 at 10:15