1

使用 NetBeans 和 GlassFish,我正在开发一个简单的独立应用程序,该应用程序Tweet从 REST 服务获取 ' 列表。除其他外,这些对象包含一个名为 的变量tweet,这是我希望在其他应用程序中看到的字符串值。

我已经构建了网站应用程序并在其中创建了一个新类:

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();
    }
}

在独立应用程序中,我创建了一个带有按钮的小表单。按下那个按钮,我想抓住那些推文。

在使用 NetBeans 添加 REST 客户端类时,我将其链接到网站的服务。它生成了一个名为 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);
    }
}

在 actionbutton 执行方法中,我试图使用该类来获取推文。这样做时,它会要求Class<T> responseType在用户名旁边输入一个应该在其上发布推文的用户名。

表单的代码如下所示:

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());
}

所以,简而言之,我的问题如下:我需要插入一个Class<T> responseType作为参数,为什么?我应该使用什么作为参数,或者更好的是,我怎样才能避免这样做而只插入用户名作为参数?

接下来,我是否需要自己在指定要访问哪个 URL 的地方输入代码?或者这一切都已经完成并通过生成客户端类来工作?

4

1 回答 1

3

Ok, there are some issues with your client code:

Problem 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. 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).

Problem 2

Your REST client class does not need to have parameterized generic functions. 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. 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();
    }
}
于 2013-01-22T17:47:11.743 回答