【问题标题】:Can't generate properly formatted XML and JSON at the same time无法同时生成格式正确的 XML 和 JSON
【发布时间】:2017-09-29 14:05:31
【问题描述】:

首先,在你决定结束我的问题之前,我已经尝试了this 解决方案,但它对我不起作用。

我有一个 REST 服务,它应该返回 JSONXML,具体取决于 Accept 标头。我可以让它生成正确的 JSON,但不能生成 XML。当我修复 XML 时,JSON 被搞砸了。下面我展示我的代码。

XML 看起来不错,但 JSON 不行

Message.java

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Message {
    int id;
    String text;

    @XmlElementWrapper
    @XmlElementRef
    List<Comment> comments;

    public Message() {

    }
    // getters and setters
}

Comment.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "comment")
public class Comment {
    int id;
    String text;

    public Comment() {

    }
    //getters and setters
}

MessageResource.java

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;


@Path("messages")
public class MessageResource {

    DBUtils db = new DBUtils();

    @GET
    @Produces(MediaType.APPLICATION_XML)
    public Response getXML() {
        List<Message> messages = db.getMessages();
        return Response.ok(messages.toArray(new Message[messages.size()]), MediaType.APPLICATION_XML).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getJSON() {
        List<Message> messages = db.getMessages();
        return Response.ok(messages.toArray(new Message[messages.size()]), MediaType.APPLICATION_JSON).build();
    }
}

这是XML的结果,没问题:

<messages>
    <message>
        <id>1</id>
        <text>Java is an OOP language.</text>
        <comments>
            <comment>
                <id>20</id>
                <text>That's correct.</text>
            </comment>
            <comment>
                <id>30</id>
                <text>test test</text>
            </comment>
        </comments>
    </message>
    <message>
        <id>1</id>
        <text>Java is an OOP language.</text>
        <comments>
            <comment>
                <id>20</id>
                <text>That's correct.</text>
            </comment>
            <comment>
                <id>30</id>
                <text>test test.</text>
            </comment>
        </comments>
    </message>
</messages>

这是JSON的结果,注意comments。我只需要一个comments 数组。

[
  {
    "id": 1,
    "text": "Java is an OOP language.",
    "comments": {
      "comment": [
        {
          "id": 20,
          "text": "That's correct."
        },
        {
          "id": 30,
          "text": "test test"
        }
      ]
    }
  },
  {
    "id": 1,
    "text": "Java is an OOP language.",
    "comments": {
      "comment": [
        {
          "id": 20,
          "text": "That's correct."
        },
        {
          "id": 30,
          "text": "test test."
        }
      ]
    }
  }
]

修复 JSON 会打乱 XML 响应

如果我从 Message 类中删除 @XmlElementWrapper@XmlElementRef 注释,那么它适用于 JSON,但不适用于 XML。

Message.jave

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Message {
    int id;
    String text;

    List<Comment> comments;

    public Message() {

    }
   //getters and setters
}

CommentMessageResource 类保持不变。

这是我得到的结果:

JSON - 好的

[
  {
    "id": 1,
    "text": "Java is an OOP language.",
    "comments": [
      {
        "id": 20,
        "text": "That's correct."
      },
      {
        "id": 30,
        "text": "test test"
      }
    ]
  },
  {
    "id": 1,
    "text": "Java is an OOP language.",
    "comments": [
      {
        "id": 20,
        "text": "That's correct."
      },
      {
        "id": 30,
        "text": "test test."
      }
    ]
  }
]

XML - 错误

<messages>
    <message>
        <id>1</id>
        <text>Java is an OOP language.</text>
        <comments>
            <id>20</id>
            <text>That's correct.</text>
        </comments>
        <comments>
            <id>30</id>
            <text>test test</text>
        </comments>
    </message>
    <message>
        <id>1</id>
        <text>Java is an OOP language.</text>
        <comments>
            <id>20</id>
            <text>That's correct.</text>
        </comments>
        <comments>
            <id>30</id>
            <text>test test.</text>
        </comments>
    </message>
</messages>

有谁知道如何让这两者一起工作?我发现的唯一解决方案是对 XML 使用 JAXB,对 JSON 使用 GSON,但我必须使用 GSON 手动创建 JSON 对象。

谢谢!

【问题讨论】:

  • 您查看过JacksonJaxbJSON 注释吗?喜欢JsonType..
  • @ulab,你能告诉我一个如何使用它的例子吗?我以前没见过。

标签: json xml rest jaxb


【解决方案1】:

我提出的解决方案将 JAXB 用于 XML(就像您一样)。但是对于 JSON,它使用 Jackson-JAXRS(不像你),例如在这个 answer 中描述的。 因此,您需要使用 Jackson-JAXRS(例如来自 Maven),而不是使用 GSON。

要获得所需的 XML 和 JSON 输出,您需要调整注解 Message 类中的 List&lt;Comment&gt; comments 属性。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Message {
    int id;
    String text;

    @XmlElementWrapper(name="comments")
    @XmlElementRef
    @JsonUnwrapped
    List<Comment> comments;

    //getters and setters
}

通过@XmlElementRef,您可以将每个Comment 对象写为&lt;comment&gt; 元素。最后,通过@XmlElementWrapper(name="comments"),您可以将所有这些包裹在&lt;comments&gt; 元素中。

XML 输出为:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<messages>
  <message>
    <id>1</id>
    <text>Java is an OOP language.</text>
    <comments>
      <comment>
        <id>20</id>
        <text>That's correct.</text>
      </comment>
      <comment>
        <id>30</id>
        <text>test test.</text>
      </comment>
    </comments>
  </message>
  <message>
    <id>1</id>
    <text>Java is an OOP language.</text>
    <comments>
      <comment>
        <id>20</id>
        <text>That's correct.</text>
      </comment>
      <comment>
        <id>30</id>
        <text>test test.</text>
      </comment>
    </comments>
  </message>
</messages>

通过@JsonUnwrapped(从包com.fasterxml.jackson.annotation 导入),您可以将List&lt;Comment&gt; comments 写成一个普通的对象数组。

JSON 输出为:

[
  {
    "id": 1,
    "text": "Java is an OOP language.",
    "comments": [
      {
        "id": 20,
        "text": "That's correct."
      },
      {
        "id": 30,
        "text": "test test."
      }
    ]
  },
  {
    "id": 1,
    "text": "Java is an OOP language.",
    "comments": [
      {
        "id": 20,
        "text": "That's correct."
      },
      {
        "id": 30,
        "text": "test test."
      }
    ]
  }
]

【讨论】:

  • 谢谢!您的解决方案正在生成正确的 XML 和几乎正确的 JSON,但数组名称为“comment”而不是“cmets”。我必须更改 XML 注释才能使其正常工作。我使用了这些注释XMLElementWrapper(name="comments") @XMLElementRef @JsonUnrwapped
  • @TurikMirash 感谢您的反馈!我用您改进的 XML 注释更新了我的答案。
猜你喜欢
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
相关资源
最近更新 更多