简体   繁体   English

在我的REST客户端中获取REST服务数据

[英]Getting REST Service data in my REST client

Using NetBeans and GlassFish, I'm developing a simple standalone application that gets a list of Tweet 's from a REST service. 使用NetBeans和GlassFish,我正在开发一个简单的独立应用程序,它从REST服务中获取Tweet的列表。 Those objects contain, amongst others, a variable called tweet , wich is the String-value I'd like to see in the other application. 这些对象包含一个名为tweet的变量,它是我想在另一个应用程序中看到的String值。

I've built the website application and created a new class in this: 我已经构建了网站应用程序并在此创建了一个新类:

RESTService.java: RESTService.java:

package service;

import domain.Tweet;
import domain.User;
import java.util.Collection;
import java.util.Date;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@Path("/rest")
public class RESTService {

    @Inject
    KwetterService service;

    @GET
    @Path("/{user}")
    public User getUser(@PathParam("user") String userName)
    {
        return service.findByName(userName);
    }

    @GET
    @Path("/{user}/tweets")
    @Produces(MediaType.TEXT_XML)
    public Collection<Tweet> getTweets(@PathParam("user") String userName)
    {
        User user = service.findByName(userName);
        return user.getTweets();
    }
}

In the standalone application, I've created a small form with a button. 在独立应用程序中,我创建了一个带有按钮的小表单。 With a press on that button, I'd like to grab those tweets. 按下那个按钮,我想抓住那些推文。

When using NetBeans to add a REST client class, I linked it to the service of the website. 使用NetBeans添加REST客户端类时,我将其链接到网站的服务。 It generated a class I called RestClient.java: 它生成了一个名为RestClient.java的类:

package service;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;

public class RestClient {
    private WebResource webResource;
    private Client client;

    public RestClient() {
    }

    public <T> T getUser(Class<T> responseType, String user) throws UniformInterfaceException {
        WebResource resource = webResource;
        resource = resource.path(java.text.MessageFormat.format("{0}", new Object[]{user}));
        return resource.get(responseType);
    }

    public <T> T getTweets(Class<T> responseType, String user) throws UniformInterfaceException {
        WebResource resource = webResource;
        resource = resource.path(java.text.MessageFormat.format("{0}/tweets", new Object[]{user}));
        return resource.accept(javax.ws.rs.core.MediaType.TEXT_XML).get(responseType);
    }
}

In the actionbutton performed method, I'm trying to use that class to gain tweets. 在actionbutton执行的方法中,我正在尝试使用该类来获取推文。 When doing so, it asks for a Class<T> responseType next to the username on which it should get tweets on. 执行此操作时,它会在用户名旁边请求Class<T> responseType ,它应该在其上发送推文。

The code of the form looks like this: 表单的代码如下所示:

private void btnZoekFollowersActionPerformed(java.awt.event.ActionEvent evt) {                                              
        String userName = txtZoekTweets.getText(); //de naam van de user
        RestClient client = new RestClient();
        Collection<Tweet> tweets = client.getTweets(MediaType.TEXT_XML, userName);
        //What to insert for mediatype? Above gives an error since it requires Class<T> responseType
        System.out.println("Datasize: " + data.size());
}

So, in short, my question is as follows: I need to insert a Class<T> responseType as parameter, why? 所以,简而言之,我的问题如下:我需要插入一个Class<T> responseType作为参数,为什么? And what should I use as parameter or, better, how can I avoid having to do this and instead only insert the username as parameter? 我应该使用什么作为参数,或者更好的是,我如何避免必须这样做而只是插入用户名作为参数?

And next to this, do I need to type code myself somewhere where I specify which URL to approach? 接下来,我是否需要在我指定要接近哪个URL的地方输入代码? Or is this all set and working through generating the client-class? 或者这一切是通过生成客户端类来设置和工作的吗?

Ok, there are some issues with your client code: 好的,您的客户端代码存在一些问题:

Problem 1 问题1

You are confusing media type with the response entity type. 您将媒体类型与响应实体类型混淆。 The Jersey WebResource class expects that when you use the method get , that you supply the expected entity type that the response should be marshaled into. Jersey WebResource类期望当您使用方法get时,您提供应该将响应封送到的预期实体类型 If you want to specify the expected media type then you need to do that by appending an Accept header, via the accept method (which you are doing in your getTweets method, but not getUser ). 如果要指定预期的媒体类型,则需要通过accept方法(您在getTweets方法中执行,但不是getUser )附加Accept标头来执行此操作。

Problem 2 问题2

Your REST client class does not need to have parameterized generic functions. 您的REST客户端类不需要具有参数化的泛型函数。 You have already defined your methods to be aware of what kind of object they are returning, so use those objects in the method signature! 您已经定义了方法以了解它们返回的对象类型,因此请在方法签名中使用这些对象!

Solution

Overall I would expect your client to look like this: 总的来说,我希望你的客户看起来像这样:

public class RestClient {
    private Client client;
    private WebResource webResource;

    public RestClient() {
        super();
    }

    public User getUser(String userName) throws UniformInterfaceException {
        final WebResource userResource = webResource
           .path(String.format("/user/%s", userName))
           .accept(MediaType.TEXT_XML) ;
        return userResource.get(User.class);
    }

    public Collection<Tweet> getTweets(String userName) throws UniformInterfaceException {
        final WebResource tweetResource = webResource
           .path(String.format("/user/%s/tweets", userName))
           .accept(MediaType.TEXT_XML) ;
        return tweetResource.get(new GenericType<Collection<Tweet>>(){});
    }
}

You will notice I added a user prefix to the resource URL's. 您会注意到我在资源URL中添加了user前缀。 You can remove it if you wish, but it will make it easier to maintain your application as you add more resource endpoints. 您可以根据需要将其删除,但在添加更多资源端点时,可以更轻松地维护应用程序。 If you decide to keep it, then you will need this modification on your server side: 如果您决定保留它,那么您将需要在服务器端进行此修改:

@Path("/rest")
public class RESTService {

    @Inject
    KwetterService service;

    @GET
    @Path("/user/{userName}")
    public User getUser(@PathParam("userName") String userName)
    {
        return service.findByName(userName);
    }

    @GET
    @Path("/user/{userName}/tweets")
    @Produces(MediaType.TEXT_XML)
    public Collection<Tweet> getTweets(@PathParam("userName") String userName)
    {
        User user = service.findByName(userName);
        return user.getTweets();
    }
}

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

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