JAX-RS客户端样本的样本在哪里?

时间:2015-03-30 00:47:46

标签: java rest java-ee jax-rs yahoo-api

我了解Java API for Yahoo Finance。我正在寻找一个样本"你好世界"客户端,例如,雅虎财经,或者,也许,一些其他公开可用的RESTful API来测试。

另见:

https://apexapps.oracle.com/pls/apex/f?p=44785:24:0::::P24_CONTENT_ID,P24_PREV_PAGE:8145,1

https://jersey.java.net/documentation/latest/client.html

上面的泽西示例似乎没问题。只是让它适应雅虎财经?

(诚然,这不是一个研究得很好的问题。只是试图避免陷入兔子洞。)

1 个答案:

答案 0 :(得分:2)

您提供的链接是指向Yahoo API的Java库的链接,并没有真正显示我们可以从任何客户端使用的“原始”REST API。所以我会将您重定向到另一个API。由于我们使用的是Stackoverflow,因此使用Stack Exchange API不适合。

如果向下滚动到页面底部,您将看到API。有些是安全的API,但这是一个更复杂的讨论,你需要了解一些关于OAuth的知识才能让它们发挥作用。我现在暂时退出讨论。

但是,如果没有注册任何帐户(或注册Stack应用程序),我们可以针对诸如答案,问题等内容做出简单的GET请求(不需要授权的正常事项;简单只读)< / p>

如果您查看API,请转到问题,您会看到指向

的链接
  

/questions/{ids}    获取由一组ID标识的问题。

点击它,你会在底部看到这个

enter image description here

29336802字段中输入id(这是此问题的ID)。您应该看到URL更改,{id}替换为您输入的ID。现在如何运行。你应该看到这个JSON响应

{
    "items": [
        {
            "tags": [
                "web-services",
                "rest",
                "java-ee",
                "jax-rs",
                "yahoo-api"
            ],
            "owner": {
                "reputation": 1582,
                "user_id": 262852,
                "user_type": "registered",
                "accept_rate": 69,
                "profile_image": "https://www.gravatar.com/avatar/e4e17e45f2e8cc967a8695131910f365?s=128&d=identicon&r=PG",
                "display_name": "Thufir",
                "link": "http://stackoverflow.com/users/262852/thufir"
            },
            "is_answered": false,
            "view_count": 6,
            "answer_count": 0,
            "score": 0,
            "last_activity_date": 1427676465,
            "creation_date": 1427676465,
            "question_id": 29336802,
            "link": "http://stackoverflow.com/questions/29336802/where-is-a-sample-jax-rs-client-sample",
            "title": "where is a sample JAX-RS client sample?"
        }
    ],
    "has_more": false,
    "quota_max": 300,
    "quota_remaining": 267
}

现在我们知道JSON响应的格式,我们可以使用客户端代码进行操作。

对于该示例,我使用Maven,并添加这两个依赖项

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.16</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.16</version>
</dependency>

这是代码,然后是结果。我将在后面解释代码

public class Sample {

    public static void main(String[] args) throws Exception {
        final String url = "http://api.stackexchange.com/2.2/questions/29336802";
        Client client = ClientBuilder.newClient();
        client.register(GZipEncoder.class);
        WebTarget target = client.target(url);
        target = target.queryParam("order", "desc")
                .queryParam("sort", "activity")
                .queryParam("site", "stackoverflow");

        Response response = target.request()
                .accept("application/json; charset=utf-8")
                .acceptEncoding("gzip").get();

        String json = response.readEntity(String.class);
        response.close();

        ObjectMapper mapper = new ObjectMapper();

        Map<String, Object> map = mapper.readValue(json, 
                TypeFactory.defaultInstance().constructMapType(
                        Map.class, String.class, Object.class));

        List<LinkedHashMap> items = (List<LinkedHashMap>)map.get("items");
        Map<String, Object> itemMap = items.get(0);

        Map<String, Object> userMap = (Map<String, Object>)itemMap.get("owner"); 
        Integer userId = (Integer)userMap.get("user_id");
        String displayName = (String)userMap.get("display_name");
        String profileImageUrl = (String)userMap.get("profile_image");

        Image image = ImageIO.read(new URL(profileImageUrl));
        JLabel label = new JLabel(new ImageIcon(image));

        JPanel panel = new JPanel(new BorderLayout());

        panel.add(label, BorderLayout.PAGE_START);
        panel.add(new JLabel("User ID: " + userId));
        panel.add(new JLabel("Display Name: " + displayName), BorderLayout.PAGE_END);

        JOptionPane.showMessageDialog(null, panel);    
    }
}

结果:

enter image description here

说明:

现在已经有很多Stack交换Java客户端,但我只是在低层展示如何做到这一点。

首先,我们构建Client并指定目标

final String url = "http://api.stackexchange.com/2.2/questions/29336802";
Client client = ClientBuilder.newClient();
client.register(GZipEncoder.class);
WebTarget target = client.target(url);
target = target.queryParam("order", "desc")
        .queryParam("sort", "activity")
        .queryParam("site", "stackoverflow");

您可以通过右键单击上图中的链接获取网址,然后(在Firefox中)从上下文菜单中选择[Copy Link Location]。它会给你

  

http://api.stackexchange.com/2.2/questions/29336802?order=desc&sort=activity&site=stackoverflow

(请记住再次输入id。当我们点击“run”时,第一次请求我,将其删除)

您可以看到我的代码中的网址不同。我实际上只是拆分查询参数,只是为了更好地了解我们可以用Client API做什么。我们注册GZipEncoder,因为响应将被压缩。

然后我们构建请求,并通过最终get()调用发送请求。

Response response = target.request()
        .accept("application/json; charset=utf-8")
        .acceptEncoding("gzip").get();

我们使用请求构建器方法acceptacceptEncoding设置了几个标头,它们将分别设置AcceptAccept-Encoding标头。

然后我们将响应主体反序列化为String

String json = response.readEntity(String.class);
response.close();

接下来的几行,你必须对JSON有一点了解,以及Jackson的默认映射如何将JSON部分映射到Java Objects。这可能有点令人困惑,但因为我不想为这个例子创建POJO(因为这是与Jacskon一起工作的最常用方式),所以我只是将JSON部分映射到默认集合。

ObjectMapper mapper = new ObjectMapper();

Map<String, Object> map = mapper.readValue(json, 
        TypeFactory.defaultInstance().constructMapType(
                Map.class, String.class, Object.class));

List<LinkedHashMap> items = (List<LinkedHashMap>)map.get("items");
Map<String, Object> itemMap = items.get(0);

Map<String, Object> userMap = (Map<String, Object>)itemMap.get("owner"); 
Integer userId = (Integer)userMap.get("user_id");
String displayName = (String)userMap.get("display_name");
String profileImageUrl = (String)userMap.get("profile_image");

然后我简单地从JSON中提取了一些细节,如用户ID和显示名称。还有您的个人资料图片的网址,我要求ImageIO.read(URL)获取实际图片。其余的代码只是一些GUI相关的东西来呈现我提取的信息

Image image = ImageIO.read(new URL(profileImageUrl));
JLabel label = new JLabel(new ImageIcon(image));

JPanel panel = new JPanel(new BorderLayout());

panel.add(label, BorderLayout.PAGE_START);
panel.add(new JLabel("User ID: " + userId));
panel.add(new JLabel("Display Name: " + displayName), BorderLayout.PAGE_END);

JOptionPane.showMessageDialog(null, panel); 

Jersey客户端API在很大程度上是标准的JAX-RS API,在link you provided中有详细记录。为了进一步了解它,我建议你彻底了解它。