在Jersey中,你如何处理深度嵌套的复杂对象的@POST参数?

时间:2013-09-04 16:54:39

标签: java rest jersey jersey-1.0

我在这里使用Jersey 1.x并且我有一个@POST方法,需要通过深度嵌套的复杂对象发送。我不确定我的所有选择,但似乎有很多described in this documentation

  

通常,方法参数的Java类型可以是:

     
      
  1. 是原始类型;

  2.   
  3. 有一个接受单个String参数的构造函数;

  4.   
  5. 有一个名为valueOf或fromString的静态方法,它接受一个String参数(例如,参见Integer.valueOf(String)和   java.util.UUID.fromString(字符串));或

  6.   
  7. Be List,Set或SortedSet,其中T满足上面的2或3。生成的集合是只读的。

  8.   

理想情况下,我希望我可以定义这样的方法:

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("complexObject")
public void complexObject(@FormParam("complexObject") ComplexObject complexObject) throws Exception {

但是我猜我只能满足上述要求(在我的情况下,它没有)。对我来说,似乎我有一个选择。

选项1:实施fromString

实施上述第3项。

选项2:传递complexObject

complexObject分解成碎片,以便参数变为:

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("complexObject")
public void complexObject(@FormParam("piece1") LessComplexPiece lessComplexPiece1, 
@FormParam("piece2") LessComplexPiece lessComplexPiece2, 
@FormParam("piece3") LessComplexPiece lessComplexPiece3) throws Exception {

如果LessComplexPiece不满足上述要求,这可能还不够。我想知道这里最好的选择是什么。在这种情况下人们通常会做些什么?以下是我能想到的利弊:

实施fromString

的缺点
  • 必须维护自定义反序列化程序。每次修改类时,此反序列化程序都可能会中断。一般来说,存在更多的漏洞风险。
  • 可能无法生成描述复杂对象部分的文档。我必须亲自写下来。
  • 对于复杂对象的每一部分,我都必须编写自己的转换和验证逻辑。
  • 我不确定帖子数据会是什么样子。但是,这可能使某人很难从网页表单调用API。如果资源接受原语,那将很容易。 EG:complexObject=seralizedString vs firstName=JohnlastName=Smith
  • 您可能因各种原因无法修改课程(谢天谢地,这不是对我的限制)

实施fromString

的优点
  • 这可以避免使用大量参数的方法。这将使API不那么令人生畏。
  • 这个论点处于我希望在我的方法体中工作的抽象层次:
  • 我不需要手工将各个部分组合在一起(技术上我会,它只需要在解串器方法中)
  • 反序列化器可以是一个自动化过程的库(XStream,gensen等),为我节省了大量时间。这可以减轻bug风险。
  • 如果您将对象展平为片段,则可能会遇到“命名空间”冲突。例如,假设通过Employee发送。如果他有Boss,您现在必须提供EmployeeFirstNameBossFirstName。如果您只是反序列化对象,则可以适当地嵌套数据,而不必在参数名称中包含上下文。

那么我应该选择哪个选项?是否有第三种选择我不知道?

3 个答案:

答案 0 :(得分:1)

对于复杂对象模型,您可能需要考虑使用JSON或XML绑定而不是URL编码的字符串来将对象传递给资源调用,以便依赖JAXB框架? Jersey客户端库与JAXB兼容,如果您注释类@XmlElementRoot,则可以透明地处理所有编组。

对于文档,如果选择XML绑定,XSD是一个很好的起点。 其他REST文档工具(如enunciate)可以将自动生成提升到一个新的水平。

答案 1 :(得分:1)

我知道这个问题很老但是如果有人遇到这个问题,那么自JAX-RS 2.0以来就有了更好的解决方案。解决方案是@BeanParam。由于文件:

  

可用于注入自定义JAX-RS"参数聚合器的注释" value对象分为资源类字段,属性或资源方法参数。   JAX-RS运行时将实例化该对象,并使用@XxxParam注释(@ PathParam,@ FormParam ...)或@Context注释中的任何一个注入所有它的字段和属性。对于POJO类,同样的实例化和注入规则适用于实例化和注入请求范围的根资源类。

如果您正在寻找有关其工作原理的详细说明,请查看我发现的文章: http://java.dzone.com/articles/new-jax-rs-20-%E2%80%93-beanparam

答案 2 :(得分:0)

将对象转换为例如的特殊处理程序怎么样? json - kryo如果你更喜欢表演?你得到了couple options

另见persistence ignorance