有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXRS客户机示例在哪里?

我知道Java API for Yahoo Finance。我正在寻找一个示例“hello world”客户端,它使用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) 个答案

  1. # 1 楼答案

    您提供的链接是指向Yahoo API的Java库的链接,并没有真正显示我们可以从任何客户端使用的“原始”REST API。因此,我将把您重定向到另一个API。既然我们在Stackoverflow上,那么使用Stack Exchange API是否合适呢

    如果你向下滚动到页面底部,你会看到API。有些是安全的API,但这是一个更复杂的讨论,您需要了解一些关于OAuth的知识才能让它们正常工作。我暂时不讨论这个问题

    但是,无需注册任何帐户(或注册Stack应用程序),我们就可以对答案、问题等进行简单的GET请求(不需要授权的普通事情;简单的只读)

    如果您查看API,请转到问题,您将看到

    /questions/{ids}       Get the questions identified by a set of ids.

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

    enter image description here

    id字段中键入29336802(这是这个问题的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 exchange 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");
    

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

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

    (记得再次输入id。当我们点击“run”时,我的第一个请求被删除)

    你可以看到我代码中的URL是不同的。实际上,我只是拆分了查询参数,以便更好地了解如何使用客户端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对象。这可能有点令人困惑,但因为我不想为这个示例创建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和显示名。还有你的个人资料图片的url,我用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中有很好的文档记录。为了进一步了解它,我建议你仔细阅读一下