我将 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 不正确(请参阅下面的“ExternalFacilities”)。如果我将嵌套列表定义为 ArrayList 子类,则 JSON 显示正确但 XML 不正确(请参阅下面的“ExternalLocations”)。
显示“设施”列表正确但“位置”不正确的 XML 示例
看到没有 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>
<id>1</id>
<kind>REGION</kind>
<name>London</name>
</locations>
<locations>
<id>2</id>
<kind>REGION</kind>
<name>Manchester</name>
</locations>
</organisation>
显示“位置”列表正确但“设施”列表不正确的 JSON 示例
看到“设施”列表是一个包含 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 header 以使 Jersey 返回 JSON 而不是 XML。以下是类(class)的摘录:
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但我并不想在我的列表中混合对象的类型。
最佳答案
您可以执行以下操作以获得所需的 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;
}
}
了解更多信息
关于java - JAXB for lists 为 JSON 或 XML 自然返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20890731/
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998