GSON:将 json 字符串转换为 Java 对象时出现非法参数异常

问题描述 投票:0回答:1

我正在使用 Youtube API。我可以将 java 对象转换为 json 字符串。但是当我尝试反转它(json 字符串到 java 对象)时,它会抛出异常:

Can not set com.google.api.services.youtube.model.CommentThreadSnippet field com.google.api.services.youtube.model.CommentThread.snippet to java.util.LinkedHashMap
。为什么会出现此错误以及如何修复它?

这有效:

  CommentThread commentThread = getItSomehow()
  Gson gson = new Gson();
  String jsonStr = gson.toJson( commentThread );

反向抛出异常:

 CommentThread fromJson = gson.fromJson( jsonStr, CommentThread.class );

这是 CommentThread 类:

@SuppressWarnings("javadoc")
    public final class CommentThread extends com.google.api.client.json.GenericJson {

  /**
   * Etag of this resource.
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private java.lang.String etag;

  /**
   * The ID that YouTube uses to uniquely identify the comment thread.
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private java.lang.String id;

  /**
   * Identifies what kind of resource this is. Value: the fixed string "youtube#commentThread".
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private java.lang.String kind;

  /**
   * The replies object contains a limited number of replies (if any) to the top level comment found
   * in the snippet.
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private CommentThreadReplies replies;

  /**
   * The snippet object contains basic details about the comment thread and also the top level
   * comment.
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private CommentThreadSnippet snippet;

  /**
   * Etag of this resource.
   * @return value or {@code null} for none
   */
  public java.lang.String getEtag() {
    return etag;
  }

  /**
   * Etag of this resource.
   * @param etag etag or {@code null} for none
   */
  public CommentThread setEtag(java.lang.String etag) {
    this.etag = etag;
    return this;
  }

  /**
   * The ID that YouTube uses to uniquely identify the comment thread.
   * @return value or {@code null} for none
   */
  public java.lang.String getId() {
    return id;
  }

  /**
   * The ID that YouTube uses to uniquely identify the comment thread.
   * @param id id or {@code null} for none
   */
  public CommentThread setId(java.lang.String id) {
    this.id = id;
    return this;
  }

  /**
   * Identifies what kind of resource this is. Value: the fixed string "youtube#commentThread".
   * @return value or {@code null} for none
   */
  public java.lang.String getKind() {
    return kind;
  }

  /**
   * Identifies what kind of resource this is. Value: the fixed string "youtube#commentThread".
   * @param kind kind or {@code null} for none
   */
  public CommentThread setKind(java.lang.String kind) {
    this.kind = kind;
    return this;
  }

  /**
   * The replies object contains a limited number of replies (if any) to the top level comment found
   * in the snippet.
   * @return value or {@code null} for none
   */
  public CommentThreadReplies getReplies() {
    return replies;
  }

  /**
   * The replies object contains a limited number of replies (if any) to the top level comment found
   * in the snippet.
   * @param replies replies or {@code null} for none
   */
  public CommentThread setReplies(CommentThreadReplies replies) {
    this.replies = replies;
    return this;
  }

  /**
   * The snippet object contains basic details about the comment thread and also the top level
   * comment.
   * @return value or {@code null} for none
   */
  public CommentThreadSnippet getSnippet() {
    return snippet;
  }

  /**
   * The snippet object contains basic details about the comment thread and also the top level
   * comment.
   * @param snippet snippet or {@code null} for none
   */
  public CommentThread setSnippet(CommentThreadSnippet snippet) {
    this.snippet = snippet;
    return this;
  }

  @Override
  public CommentThread set(String fieldName, Object value) {
    return (CommentThread) super.set(fieldName, value);
  }

  @Override
  public CommentThread clone() {
    return (CommentThread) super.clone();
  }

}

以下是例外的详细信息。

Throwable: Can not set com.google.api.services.youtube.model.CommentThreadSnippet field com.google.api.services.youtube.model.CommentThread.snippet to java.util.LinkedHashMap
java.lang.IllegalArgumentException: Can not set com.google.api.services.youtube.model.CommentThreadSnippet field com.google.api.services.youtube.model.CommentThread.snippet to java.util.LinkedHashMap
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.lang.reflect.Field.set(Field.java:764)
    at com.google.api.client.util.FieldInfo.setFieldValue(FieldInfo.java:245)
    at com.google.api.client.util.FieldInfo.setValue(FieldInfo.java:206)
    at com.google.api.client.util.GenericData.put(GenericData.java:103)
    at com.google.api.client.util.GenericData.put(GenericData.java:47)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:189)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:146)
    at com.google.gson.Gson.fromJson(Gson.java:755)
    at com.google.gson.Gson.fromJson(Gson.java:721)
    at com.google.gson.Gson.fromJson(Gson.java:670)
    at com.google.gson.Gson.fromJson(Gson.java:642)
    at sam.ut.CommentThreads.handleCommentsThreads(CommentThreads.java:157)
    at sam.ut.CommentThreads.DownloadCommentsForThisVideo(CommentThreads.java:84)
    at sam.ut.CommentThreads.main(CommentThreads.java:66)

编辑:这是 JSON:

{
  "etag": "\"0Fu6lI6VPLdRMlQU3wwNcowdAUs/F7bYskj8z3daRWhUSU5zInnZkqw\"",
  "id": "z12wxpxozzy1tdxop04cjd1rjzq4cp2jgfw",
  "kind": "youtube#commentThread",
  "snippet": {
    "canReply": true,
    "isPublic": true,
    "topLevelComment": {
      "etag": "\"0Fu6lI6VPLdRMlQU3wwNcowdAUs/PzVv_VFrN7CZoVSIIlPnVsEIwE0\"",
      "id": "z12wxpxozzy1tdxop04cjd1rjzq4cp2jgfw",
      "kind": "youtube#comment",
      "snippet": {
        "authorChannelId": {
          "value": "UCOjTszsvhfAKFQprwN3ETLQ"
        },
        "authorChannelUrl": "http://www.youtube.com/channel/UCOjTszsvhfAKFQprwN3ETLQ",
        "authorDisplayName": "Spruce Moose Arts",
        "authorGoogleplusProfileUrl": "https://plus.google.com/102869292172467105853",
        "authorProfileImageUrl": "https://lh6.googleusercontent.com/-eJGw19enrkQ/AAAAAAAAAAI/AAAAAAAAAyg/khd3HglROx4/photo.jpg?sz=50",
        "canRate": true,
        "likeCount": 0,
        "publishedAt": "2016-06-13T22:49:52.000Z",
        "textDisplay": "The man behind the camera which recorded this, must be very shaky, \ncondsidering the amount of warp stabilization on this video :P Also, i \nthink this is a matter of personal taste. I personally think the car WITH \npol filter looked much better.",
        "updatedAt": "2016-06-13T22:49:52.000Z",
        "videoId": "YcZkCnPs45s",
        "viewerRating": "none"
      }
    },
    "totalReplyCount": 0,
    "videoId": "YcZkCnPs45s"
  }
}
java json gson
1个回答
0
投票

我在这个问题上迟到了,但决定回复以防将来有人碰到这个帖子。我遇到了同样的错误,这似乎是由于

CommentThread
对象的编组方式造成的。很奇怪。我创建了一个解决方法来重建
youtube#commentThread
对象类型。您拥有的 JSON 是正确的,足以从单独的部分构建
youtube@commentThread
。您需要解构 JSON:

  1. 拉出 topLevelComment - 您会将其映射到

    com.google.api.services.youtube.model.Comment

  2. 拉出顶部片段并将其映射到

    com.google.api.services.youtube.model.CommentThreadSnippet

  3. 拉出

    youtube#commentThread
    ,您会将其映射到
    com.google.api.services.youtube.model.CommentThread

  4. 然后您可以重建 CommentThread 并使用该对象处理该对象 例如:

    commentThreadSnippet.setTopLevelComment(topLevelComment);
    commentThread.setSnippet(commentThreadSnippet);
    
© www.soinside.com 2019 - 2024. All rights reserved.