繁体   English   中英

如何使用Java中的Rest模板从JSON提取数据

[英]How To Extract Data From JSON with Rest Template in Java

我必须从https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=19acc3a371d145ecb37a093f9985ea21中提取前5篇文章,其结果如下:

{
    "total": 5,
    "articles": [
{
    "source": "Ilmessaggero.it",
    "title": "Title",
    "author": "Author",
    "url": "URL"
  }
 ]
}

我这样做了,将所有JSON作为字符串作为localhost的输出...

@RequestMapping("/news")
    public Article connection() {

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

本地主机中的结果是:

{"source":null,"title":null,"author":null,"url":null}

但是现在的问题是,如何将数据放入文章列表中? 以及如何将它们保存到mongodb中? 感谢您的努力

一种简单的(即缺少异常处理等)方法如下:

首先,您需要一个类来表示您要接收的数据,并使用与API响应字段相匹配的字段,例如:

public class Article {

    private String source;
    private String title;
    ...  // more fields

   // getters and setters
}

然后,从API提取数据的代码如下所示:

RestTemplate template = ...  // initialized earlier
ResponseEntity<Article[]> response = template.exchange(
    API_URL,  // url to the api
    HttpMethod.GET,  // use the Http verb "GET"
    new HttpEntity<>(headers),  // optional headers, e.g. for basic auth
    Article[].class  // the expected response type is Article[]
);

Article[] articles = response.getBody();
List<Article> list = Arrays.asList(articles);  // if you need to use collections

注意, ResponseEntity为非null并不意味着请求成功。 您可以使用responseEntity.getStatusCode()确定responseEntity.getStatusCode()的状态码。

但是要小心,因为默认情况下,当收到非200错误代码时(在4XX和5XX代码分别为HttpClientErrorExceptionHttpServerErrorException时), RestTemplate会引发异常。 如果您想要自己的自定义错误处理,则应致电:

template.setErrorHandler(new ResponseErrorHandler() {
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        // implement here
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        // implement here
    }
});

为了持久地保留在MongoDB中,您可以使用JPA,尽管JPA由于其固有的关系性质与Mongo的非关系结构相抵触,因此不适用于MongoDB。 像Spring Data这样的东西可以更明智地映射它,值得研究: https : //spring.io/projects/spring-data-mongodb

编辑-调用此代码

通常,我将创建一个具有实现的类/接口(例如,称为ArticleResource ),如下所示:

public class ArticleResource {

    private final RestTemplate template = new RestTemplate();

    public List<Article> getAllArticles() {
        ResponseEntity<Article[]> response = template.exchange(API_URL, HttpMethod.GET, new HttpEntity<>(headers), Article[].class);

    // some error checking here

    return response.getBody() == null ? Collections.emptyList() : Arrays.asList(response.getBody());
    }
}

对于需要单个值的方法(例如, findArticleByTitle(String title) ),我通常返回Optional<Article>findArticleByTitle(String title)做法是返回Optional<List<T>> ,因为空列表已经表示“无值”)。

从那里,您可以在代码中调用:

ArticleResource resource = new ArticeResource();

// if you want to print all the names for example:
resource.getAllArticles().stream().map(Article::getName).forEach(System.out::println);

我解决了! 简而言之,Article的NewsAPI json有一个名为Source的字段,我试图将其解析为字符串,但事实并非如此! 实际上,它是一个用另一个对象描述的字段! 我只需要创建一个带有ID和名称的名为Source的类,它就可以工作! 感谢大家的努力!

这是类的代码:

public class Article {

    private Source source;

    private String author;

    private String title;

    private String url;

    //getters and setters

新闻,其中包含文章列表:

public class News {

    private int totalResults;

    private List<Article> articles;

    //getters and setters

和Source,在Article中称为:

public class Source {

    private String id;

    private String name;

    //getters and setters

这里是! 解析代码与答案相同。 只需将返回类型(Article)更改为News,并将getForObject的Article.class参数更改为News.class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM