我不确定如何最好地解释这一点,所以这可能有点长,请耐心等待。
假设我有一个带有许多属性的java bean:
public interface Customer {
public String getFirstName();
public String getLastName();
public Address getAddress(); // embedded bean with its own properties
... // lots more
}
显然,有一个相应的实现,另外还定义了适当的setter(虽然setter可能不会在某些属性的接口中公开)。
有一个服务(POJO接口+实现)定义了一系列可以对客户执行的操作(CRUD,一些find()查询等)。服务是通过Spring引导的,整个过程在本地和通过RMI工作正常。
现在我有一个客户端(iPhone应用程序)需要访问通过上述API公开的小子集功能 - 在服务操作和API属性方面都是子集。我们的想法是通过REST风格的API公开这个子集:
GET /services/customers/1234
返回
<customer>
<firstName>Homer</firstName>
<lastName>Simpson</lastName>
<city>Springfield</city>
</customer>
或者甚至
<customer firstName="Homer" lastName="Simpson" city="Springfield" />
问题是 - 我该怎么做呢?我(简要地)查看了JAXB / CXF / Jersey,看起来我必须定义一个模式,根据它生成一堆类,并将数据从我的API实体复制到这些类。有没有办法避免这一切?
理想情况下,我想在我的API实体中注释相应的属性,并让它们(并且只有它们)自动编组“自动”。如果需要,我可以为Web服务端点编写专用接口/实现;注释现有的会更好。
另一个(更紧迫的)问题是 - 我做了一些愚蠢的事吗?有更简单和/或更好的方法吗? 上次我使用Web服务是Axis 1.1次,上次我使用iPhone时从来没有:-)所以任何指针都会非常感激。
更新澄清 - 我正在寻找最简单的方法来将子集的javabean属性编组为XML(或者JSON可能?) / em>必须编写/生成另一个类来表示所述属性子集。上面的例子过于简单化,实际上API涉及很多类,相当广泛。我确实希望尽可能避免重复。
答案 0 :(得分:1)
Google搜索jaxb interface似乎表明界面在JAXB中很难处理,如java.net blog post和另一个stackoverflow question所示。
如果您的POJO是一个类而不是一个接口,可能会更容易。我正在使用RESTEasy(另一个JAX-RS实现)和JAXB,我只需要用@XmlRootElement注释我的POJO类。另一方面,我编写了自定义的http客户端代码,以便使用JAXB对相同的带注释的类进行编组/解组(如果可以使用,则可以使用RESTEasy客户端代理框架自动执行)。请注意,我没有定义架构,但是由于我可以控制RESTful Web服务的两个方面,所以我可以逍遥法外。
泽西岛有client API你可能想看看。 CXF还有一个front-end / client API,包括一个类似于RESTEasy的基于代理的机制。
查看 RESTful Java with JAX-RS 一书,其中涵盖了我发现有用的以下内容:
控制器示例:
@GET
@Produces( { MediaType.APPLICATION_XML })
@Path("/customers/{id}")
public Customer getCustomer(@PathParam("id") int id) {
...
return customer;
}
示例POJO:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
Address address;
String name;
// annotate with XmlTransient to prevent mapping this property/type to XML
@XmlTransient
String ssn;
...
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
String planet;
...
}
答案 1 :(得分:0)
我的首选是使用JAXB注释注释您已经拥有的类,并让绑定编译器根据您已有的类创建模式,方法是对注释的源文件example here运行schemagen
。
我发现JAXB非常有用,并且很容易用于创建来自java类的模式和来自模式的java类,我在创建用于服务保险策略的Web服务时使用这些模式。
答案 2 :(得分:0)
最简单的方法:使用XML序列化API,例如XStream或Simple,它们是针对您要求的这种POJO到XML类型的问题而制作的。选择子集并切换到属性很简单,如下所示:
class Customer {
@XStreamAsAttribute
String firstName;
@XStreamAsAttribute
String lastName;
@XStreamOmitField
Address address();
}