当前位置: 首页 > 知识库问答 >
问题:

Spring Hateoas的多态性

丘飞
2023-03-14

在尝试了几个变体之后,我一直在尝试让我的Spring HATEOAS控制器执行多态性。

我的第一个变体是将资源实现为资源的实例,我的对象是内容。基类定义如下:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonSubTypes({ @Type(value = Cat.class, name = "Cat"), @Type(value = Dog.class, name = "Dog") })
@JsonRootName("Animal")
public abstract class Animal
{
  :
  :
}

获取单个实例或页面时,会引发以下异常:

Could not write content: Unwrapped property requires use of type information: can not serialize without disabling `SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS`

此处提供完整的复制:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos/spring/hateoas/polymorphism/repro1

我的理解是,此错误是由ResourcesgetContent方法上的@JsonUnlie注释引起的。PagedResources显然使用了类似的方法。

我的第二次尝试是让我的类继承自ResourceSupport,以避免JSONUnrapped问题。基类现在如下所示:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonSubTypes({ @Type(value = Cat2.class, name = "Cat2"), @Type(value = Dog2.class, name = "Dog2") })
@JsonRootName("Animal2")
public abstract class Animal2 extends ResourceSupport
{
  :
  :
}

这是部分有效的。单个资源现在已正确序列化(注意@type属性):

{
   "@type":"Dog2",
   "name":"nameofdog",
   "barkVolume":1.0,
   "_links":{
      "self":{
         "href":"http://localhost:8082/animals2/nameofdog"
      }
   }
}

但是,页面没有type属性:

{
   "_embedded":{
      "Animal2s":[
         {
            "name":"nameofdog",
            "barkVolume":1.0,
            "_links":{
               "self":{
                  "href":"http://localhost:8082/animals2/nameofdog"
               }
            }
         },
         :
         :
      ]
   },
   "_links":{
      "self":{
         "href":"http://localhost:8082/animals2"
      }
   },
   "page":{
      "size":20,
      "totalElements":3,
      "totalPages":1,
      "number":0
   }
}

此重现的代码可在此处获得:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos/spring/hateoas/polymorphism/repro2

如果有人能解释一种使多态性与Spring HATEOAS相结合的方法,我将不胜感激。

共有1个答案

范承教
2023-03-14

进一步查看后,我发现了@type属性未包含在资源页面中的原因:type erasure。请参阅此问题。

有一个解决方法:不是include=JsonTypeInfo。as. PROPERTY,而是使用include=JsonTypeInfo。as.EXISTING_PROPERTY并为每个返回类型的子类添加一个属性。它不优雅,但它允许实现多态API。此解决方法的完整源代码可在此处获得:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos/spring/hateoas/polymorphism/workaround

附言:对于那些认为禁用SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS将解决第一个变体中的问题:如果您禁用该设置,类型信息将被忽略,因此@type属性不会在序列化期间添加。

 类似资料:
  • 我只是想学习,构建一个Spring HATEOAS应用程序。 我已将自定义查询添加到我的存储库中: 我得到了很好的JSON响应,但由于这是可分页的,我想要一个链接部分。。。使用上一个/下一个。 我该如何添加它? 主url提供了所有客户的列表,链接没有问题,我只想将这些链接添加到自定义可分页方法。 --编辑-- 啊! 使findAllFitered方法返回一个页面而不是列表。。。

  • 有人能提供一个简单的例子来解释Java中动态多态性和静态多态性之间的区别吗?

  • 多态的概念其实不难理解,它是指对不同类型的变量进行相同的操作,它会根据对象(或类)类型的不同而表现出不同的行为。 事实上,我们经常用到多态的性质,比如: >>> 1 + 2 3 >>> 'a' + 'b' 'ab' 可以看到,我们对两个整数进行 + 操作,会返回它们的和,对两个字符进行相同的 + 操作,会返回拼接后的字符串。 也就是说,不同类型的对象对同一消息会作出不同的响应。 看下面的实例,来

  • 问题内容: 当我开始寻找多态性的好处时,在这里发现了这个问题。但是在这里我找不到答案。让我告诉我想找到什么。这里有一些课程: 现在,我在Demo类中创建了两个对象,它们是的引用。我完全了解,我可以从对象中调用方法,但是该方法对于对象是隐藏的。现在我的问题是为什么我应该使用多态性或为什么我应该使用 当我同意的时候 多态物体的效率好还是重量轻?这两个对象的基本目的和区别是什么?有什么区别和? 问题答案

  • 问题内容: 我在使用Gson反序列化json字符串时遇到问题。我收到一系列命令。该命令可以是start,stop或其他类型的命令。我自然具有多态性,并且start / stop命令从command继承。 如何使用gson将其序列化回正确的命令对象? 似乎我只获得基本类型,即声明的类型,而从未获得运行时类型。 问题答案: 根据我的研究以及使用gson-2.0时,你确实不想使用registerType

  • 本文向大家介绍Java中的多态性,包括了Java中的多态性的使用技巧和注意事项,需要的朋友参考一下 多态是对象采取多种形式的能力。当使用父类引用来引用子类对象时,会在OOP中最常见地使用多态。 任何可以通过多个IS-A测试的Java对象都被视为多态的。在Java中,所有Java对象都是多态的,因为任何对象都将通过IS-A测试以了解其自身类型和Object类。 重要的是要知道访问对象的唯一可能方法是