【问题标题】:jax-rs Jersey @Post Response entity is emptyjax-rs Jersey @Post 响应实体为空
【发布时间】:2013-10-23 06:40:11
【问题描述】:

我正在尝试@POST 一个用户创建的对象并获得一个以不同的用户创建的有效负载作为实体的响应。虽然返回的对象存在并被填充,但在客户端它是空的。

客户端发送/服务器接收对象:

@XmlRootElement
public class TweetQuery {
    String query;
    List<TweetQueryTweet> tweets = new ArrayList<>();
    // setters and getters
}

public class TweetQueryTweet {
    private String id;
    private String text;
    // setters and getters
}

服务器接收/客户端发送对象:

@XmlRootElement
public class TweetClusters {
    List<TweetCluster> tweetClusters = new ArrayList<>();
    // setters and getters
}

public class TweetCluster {
    List<String> labels = new ArrayList<>();
    List<String> docs = new ArrayList<>();
    // setters and getters
}

客户端(Arquillian)测试:

@Test
@RunAsClient
public void test01SeeSomething(@ArquillianResource URL deploymentUrl) throws ... {

    final URI targetURI = ...;
    System.out.println("    test target:" + targetURI.toASCIIString());

    Entity<TweetQuery> tweetQuery = Entity.entity(getTestTweetQuery(), MediaType.APPLICATION_JSON);

    Client client = ClientBuilder.newBuilder().build();
    WebTarget target = client.target(targetURI.toASCIIString());

    Response response = target.request(MediaType.APPLICATION_JSON).post(tweetQuery);

    TweetClusters x = response.readEntity(TweetClusters.class);
    System.out.println("Entity:" + x);
    System.out.println("Response: " + response.getStatus());
    assertEquals(Status.OK.getStatusCode(), response.getStatus());
    assertNotNull(x);
    assertThat(x.getTweetClusters().size()).isGreaterThan(0);
}

Jersey Post 方法:

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response clusterPost(TweetQuery tweetQuery) {
    TweetClusters tweetClusters = clusterService.getTweetClusters(tweetQuery);
    System.out.println("clusterPost - in - tweetQuery: " + tweetQuery);
    System.out.println("    - out tweetClusters: " + tweetClusters);
    return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(tweetClusters).build();
}

调试:

test target:http://localhost:18080/test//cluster

clusterPost - in - tweetQuery: [TweetQuery - query:TweetQuery query, tweets:[[TweetQueryTweet - id:1, text:text 1], [TweetQueryTweet - id:2, text:text 2], [TweetQueryTweet - id:3, text:text 3]]]
    - out tweetClusters: [TweetClusters:[[TweetCluster - labels: [Other Topics], docs:[3, 2, 1]]]]
Entity:[TweetClusters:[]]
Response: 200

第 2 行 - clusterPost - in - 显示 TweetQuery 正在正确编组。 第 3 行 - clusterPost - out - 显示响应实体存在时要发送的 tweetClusters 第 4 行 - tweetClusters 没有从请求中出来


编辑

我更改了 REST 方法以返回它作为输入接收的 tweetQuery,并且它被正确返回。所以它是关于 TweetClusters 的。也许我需要一个 MessageBodyReader & Writer。或 Moxy @XmlJavaTypeAdapter。但是对于 Lists 显然是开箱即用的,因为 TweetQuery 有效。

https://stackoverflow.com/users/383861/blaise-doughan你在外面吗? :)

我错过了一些简单的东西吗?

【问题讨论】:

    标签: java rest jersey jax-rs moxy


    【解决方案1】:

    好的,我解决了。我无意中告诉了一个猪肉馅饼。当我说我有 setter 和 getter 时,我错过了 TweetClusters 的 setter。然后一旦修复,我就有一个带有参数但没有无参数构造函数的构造函数。一旦添加了无参数构造函数,一切都很好。

    总而言之,您需要在要(未)编组的对象中拥有:

    1. 如果您有 arg 构造函数,则为 no-arg 构造函数
    2. 所有元素的设置器和获取器

    如果您有更复杂的类型,包括日期和日历,则需要在 Jackson 中使用适配器 @XmlJavaTypeAdapter (Moxy) 或 @JsonSerialize.using(或在 RESTeasy 中使用 ???...)。

    有趣的是,我并不需要 @XmlRootElement (Moxy),尽管我将它留在那里以备不时之需。

    完整的答案是:

    1. 客户端(Arquillian)测试同上
    2. Jersey Post 方法同上
    3. (未)编组的对象类是:

      @XmlRootElement 公共类 TweetClusters { 列出 tweetClusters = new ArrayList();

      public void addCluster(Cluster c) {
          TweetCluster tweetCluster = new TweetCluster(c);
          tweetClusters.add(tweetCluster);
      }
      
      public List<TweetCluster> getTweetClusters() {
          return tweetClusters;
      }
      
      public void setTweetClusters(List<TweetCluster> tweetClusters) {
          this.tweetClusters = tweetClusters;
      }
      
      @Override
      public String toString() {
          return String.format("[TweetClusters:%s]", tweetClusters);
      }
      

      }

      公共类 TweetCluster { 列表标签 = new ArrayList(); 列出文档 = new ArrayList();

      public TweetCluster() {
      }
      
      public TweetCluster(Cluster c) {
          labels.add(c.getLabel());
          for (Document doc : c.getDocuments()) {
              docs.add(doc.getTitle());
          }
      }
      
      public List<String> getLabels() {
          return labels;
      }
      
      public void setLabels(List<String> labels) {
          this.labels = labels;
      }
      
      public List<String> getDocs() {
          return docs;
      }
      
      public void setDocs(List<String> docs) {
          this.docs = docs;
      }
      
      @Override
      public String toString() {
          return String.format("[TweetCluster - labels: %s, docs:%s]", labels, docs);
      }
      

      }

      公共类 TweetQuery { 字符串查询;

      List<TweetQueryTweet> tweets = new ArrayList<>();
      
      public String getQuery() {
          return query;
      }
      
      public void setQuery(String query) {
          this.query = query;
      }
      
      public List<TweetQueryTweet> getTweets() {
          return tweets;
      }
      
      public void setTweets(List<TweetQueryTweet> tweets) {
          this.tweets = tweets;
      }
      
      public void addTweets(TweetQueryTweet... queryTweets) {
          for (TweetQueryTweet tweet : queryTweets) {
              this.tweets.add(tweet);
          }
      }
      
      @Override
      public String toString() {
          return String.format("[TweetQuery - query:%s, tweets:%s]",query, tweets);
      }
      

      }

    (Arghhh,对格式感到抱歉;我无法在 SO 中修复它)

    出于调试目的,通常最好从响应中返回字符串表示形式(即 XML 或 JSON),您只需将实体类型指定为 String.class:

    String x = response.readEntity(String.class);
    

    【讨论】:

      【解决方案2】:

      尝试像这样返回响应:Response.ok(tweetClusters).build();

      【讨论】:

        【解决方案3】:

        我不确定您为什么要使用 @XmlRootElements 注释模型。所以我认为您可以删除它并确保您使用 Jackson 来序列化和反序列化您的请求和响应正文。我假设你是或 gson。

        【讨论】:

        • 不,我正在使用需要这些注释的 Moxy。我刚刚删除了它们,并且编组到 REST 方法仍然可以正常工作,我认为这不应该发生。但不能解决我遇到的问题。
        猜你喜欢
        • 2012-06-03
        • 2020-12-07
        • 2012-11-30
        • 2018-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 2014-01-24
        相关资源
        最近更新 更多