3

我在这里使用 Jersey 1.x,我有一个@POST方法需要发送一个深度嵌套的复杂对象。我不确定我的所有选择,但本文档中似乎描述了很多内容:

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

  1. 是原始类型;

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

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

  4. 是 List、Set 或 SortedSet,其中 T 满足上述 2 或 3。生成的集合是只读的。

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

@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。如果资源接受原语,那将很容易。例如:complexObject=seralizedString对比firstName=JohnlastName=Smith
  • 您可能由于各种原因无法修改课程(谢天谢地,这对我来说不是限制)

实施的优点fromString

  • 这可以避免使用大量参数的方法。这将使 API 的使用变得不那么令人生畏。
  • 这个论点处于我想在我的方法主体中工作的抽象级别:
  • 我不必手动将这些部分组合在一起(从技术上讲,我会的,它只需要在解串器方法中)
  • 反序列化器可以是一个使过程自动化的库(XStream、gensen 等)并为我节省大量时间。这可以减轻错误风险。
  • 如果您将对象展平以发送多个碎片,则可能会遇到“命名空间”冲突。例如,想象一下发送一个Employee. 如果他有 a Boss,您现在必须提供 aEmployeeFirstName和 a BossFirstName。如果您只是反序列化一个对象,您可以适当地嵌套数据,而不必在参数名称中包含上下文。

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

4

3 回答 3

1

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

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

于 2014-04-11T20:39:12.790 回答
1

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

可用于将自定义 JAX-RS“参数聚合器”值对象注入资源类字段、属性或资源方法参数的注释。JAX-RS 运行时将实例化该对象并注入其所有使用@XxxParam 注释(@PathParam、@FormParam ...)或@Context 注释之一注释的字段和属性。对于 POJO 类,应用与请求范围的根资源类的实例化和注入相同的实例化和注入规则。

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

于 2015-06-05T17:30:03.717 回答
0

如果您更喜欢性能,那么将对象转换为例如 json - kryo 的特殊处理程序怎么样?你有几个选择

又看执着无知

于 2013-09-05T05:51:16.550 回答