无法同时生成格式正确的XML和JSON

Tur*_*ash 7 xml rest json jaxb

首先,在你决定关闭我的问题之前,我已经尝试过这个解决方案,但它对我不起作用.

我有一个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
}
Run Code Online (Sandbox Code Playgroud)

Comment.java

import javax.xml.bind.annotation.XmlRootElement;

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

    public Comment() {

    }
    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是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>
Run Code Online (Sandbox Code Playgroud)

这是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."
        }
      ]
    }
  }
]
Run Code Online (Sandbox Code Playgroud)

修复JSON会弄乱XML响应

如果我从类中删除@XmlElementWrapper@XmlElementRef注释Message,那么它适用于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
}
Run Code Online (Sandbox Code Playgroud)

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."
      }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Tho*_*sch 5

我提出的解决方案使用JAXB for XML(和你一样).但对于JSON,它使用Jackson-JAXRS(与您不同),例如本答案中描述的.因此,您需要使用Jackson-JAXRS(例如来自Maven),而不是使用GSON .

要获得所需的XML和JSON输出,您需要调整类中List<Comment> comments属性的注释Message.

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

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

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

通过@XmlElementRef您将每个Comment对象写为<comment>元素.最后,通过@XmlElementWrapper(name="comments")你将所有这些包裹在一个<comments>元素中.

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>
Run Code Online (Sandbox Code Playgroud)

通过@JsonUnwrapped(从包导入com.fasterxml.jackson.annotation),您可以将其List<Comment> 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."
      }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)