我在这里使用 Jersey 1.x,我有一个@POST
方法需要发送一个深度嵌套的复杂对象。我不确定我的所有选择,但本文档中似乎描述了很多内容:
通常,方法参数的 Java 类型可能:
是原始类型;
有一个接受单个 String 参数的构造函数;
有一个名为 valueOf 或 fromString 的静态方法,它接受单个 String 参数(例如,参见 Integer.valueOf(String) 和 java.util.UUID.fromString(String));或者
是 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=John
和lastName=Smith
- 您可能由于各种原因无法修改课程(谢天谢地,这对我来说不是限制)
实施的优点fromString
- 这可以避免使用大量参数的方法。这将使 API 的使用变得不那么令人生畏。
- 这个论点处于我想在我的方法主体中工作的抽象级别:
- 我不必手动将这些部分组合在一起(从技术上讲,我会的,它只需要在解串器方法中)
- 反序列化器可以是一个使过程自动化的库(XStream、gensen 等)并为我节省大量时间。这可以减轻错误风险。
- 如果您将对象展平以发送多个碎片,则可能会遇到“命名空间”冲突。例如,想象一下发送一个
Employee
. 如果他有 aBoss
,您现在必须提供 aEmployeeFirstName
和 aBossFirstName
。如果您只是反序列化一个对象,您可以适当地嵌套数据,而不必在参数名称中包含上下文。
那么我应该选择哪个选项?有没有我不知道的第三种选择?