我使用MOXy和Jersey实现RESTful API,并希望自然地为JSON和XML返回列表,我的意思是XML包含整个集合的元素标记以及集合项,而JSON只包含集合的标记。
例如,我想要返回一个"组织"具有嵌套的设施和位置列表的资源。作为XML:
<organisation>
<id>1</id>
<name>XYZ</name>
<facilities>
<facility>
<id>1</id>
<text>Telephone</text>
</facility>
<facility>
<id>3</id>
<text>Whiteboard</text>
</facility>
</facilities>
<locations>
<location>
<id>1</id>
<kind>REGION</kind>
<name>London</name>
</location>
<location>
<id>2</id>
<kind>REGION</kind>
<name>Manchester</name>
</location>
</locations>
</organisation>
和JSON一样:
{
"id": 1,
"name": "XYZ",
"facilities": [
{
"id": 1,
"text": "Telephone"
},
{
"id": 3,
"text": "Whiteboard"
}
],
"locations": [
{
"id": 1,
"kind": "REGION",
"name": "London"
},
{
"id": 2,
"kind": "REGION",
"name": "Manchester"
}
]
}
不幸的是,我似乎无法获得一个代码库,允许我为XML和JSON返回这样的输出。如果我使用一个类来包装嵌套列表,那么XML看起来是正确的而不是JSON(参见&#34; ExternalFacilities&#34;下面)。如果我将嵌套列表定义为ArrayList
子类,则JSON显示正确但不是XML(请参阅&#34; ExternalLocations&#34;下面)。
XML示例显示&#34;设施&#34;列出正确但不是&#34;位置&#34;
看到没有包含&#34;位置&#34;的XML元素。 list(就像&#34;设施&#34;),以及每个位置都有一个复数元素名称。
<organisation>
<id>1</id>
<name>XYZ</name>
<facilities>
<facility>
<id>1</id>
<text>Telephone</text>
</facility>
<facility>
<id>3</id>
<text>Whiteboard</text>
</facility>
</facilities>
<locations>
<id>1</id>
<kind>REGION</kind>
<name>London</name>
</locations>
<locations>
<id>2</id>
<kind>REGION</kind>
<name>Manchester</name>
</locations>
</organisation>
JSON示例显示&#34;位置&#34;列出正确但不是&#34;设施&#34;
看到&#34;设施&#34; list是一个包含JSON数组的JSON对象,而我只想要JSON数组(带有复数元素名称)。
{
"id": 1,
"name": "XYZ",
"facilities": {
"facility": [
{
"id": 1,
"text": "Telephone"
},
{
"id": 3,
"text": "Whiteboard"
}
]
},
"locations": [
{
"id": 1,
"kind": "REGION",
"name": "London"
},
{
"id": 2,
"kind": "REGION",
"name": "Manchester"
}
]
}
以上示例使用相同的代码生成,只需更改Accept HTTP标头即可使Jersey返回JSON而不是XML。以下是课程的摘录:
ExternalOrganisation.java
@XmlRootElement(name="organisation")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalOrganisation {
private String name;
private ExternalFacilities facilities;
private ExternalLocations locations;
...
}
ExternalFacilities.java
@XmlRootElement(name="facilities")
public class ExternalFacilities {
@XmlElementRef
private List<ExternalFacility> list;
...
}
ExternalLocations.java
@XmlRootElement(name="locations")
public class ExternalLocations extends ArrayList<ExternalLocation> {
...
}
ExternalFacility.java
@XmlRootElement(name="facility")
@XmlType(propOrder={"id", "uri", "kind", "text"})
public class ExternalFacility extends ExternalBase {
// id inherited
private String text;
....
}
ExternalLocation.java
@XmlRootElement(name="location")
@XmlType(propOrder={"id", "kind", "name"})
public class ExternalLocation extends ExternalBase {
// id inherited
@XmlElement private LocationKind kind;
@XmlElement private String name;
...
}
最初似乎与this question类似,但我并没有尝试在我的列表中混合使用对象类型。
答案 0 :(得分:4)
您可以执行以下操作以获取所需的XML和JSON表示:
@XMLElementWrapper
而不是:
@XmlRootElement(name="organisation")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalOrganisation {
private String name;
private ExternalFacilities facilities;
private ExternalLocations locations;
...
}
您可以使用@XmlElementWrapper
执行以下操作(请参阅:http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html):
@XmlRootElement(name="organisation")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalOrganisation {
private String name;
@XmlElementWrapper
@XmlElementRef
private List<ExternalFacility> facilities;
@XmlElementWrapper
@XmlElementRef
private List<ExternalLocation> locations;
...
}
通过将包装器指定为数组名称属性,MOXy将使用@XmlElementWrapper
中的值作为JSON数组名称。
import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
public class YourApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
HashSet<Class<?>> set = new HashSet<Class<?>>(1);
set.add(YourService.class);
return set;
}
@Override
public Set<Object> getSingletons() {
MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
moxyJsonProvider.setWrapperAsArrayName(true);
HashSet<Object> set = new HashSet<Object>(1);
set.add(moxyJsonProvider);
return set;
}
}
了解更多信息