Spring HATEOS - 如何投射基本类型 class 的所有属性?

Spring HATEOS - How to project all attribute of base type class?

给定 class 的投影,有没有办法告诉 Spring 包含 类型中定义的 class 的所有默认属性Projection 注释 ?

给定 2 个实体 Class

@Entity 
@Data 
public class Client {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String nom;
    private String adresseLigne1;
    private String adresseLigne2;
    private String ville;

    @ManyToOne
    private Province province; 
    /* Many other attribute */

}

@Entity
@Data
public class Province {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;
}

每个都有一个存储库

@RepositoryRestResource(collectionResourceRel = "Client", path = "Client")
public interface ClientRepository extends PagingAndSortingRepository<Client, Long> {
    List<Client> findBy();
}

-

@RepositoryRestResource(collectionResourceRel = "Province", path = "Province")
public interface ProvinceRepository extends PagingAndSortingRepository<Province, Long> {
    List<Province> findByName(String name);
}

我为客户端获得以下默认值 json:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  }
}

有没有一种方法可以创建一个投影 return Client 的所有属性,而不必为 [=] 中的所有属性编写所有 getXXX 方法44=]客户端

@Projection(name = "inlineProvince", types = { Client.class })
public interface ClientProjection {
    /* A way to tell the projection to include all of Client attribute */
    Province getProvince();  // This is the linked object I want to add to my json output as an in-line map (i.e have the behaviour as if it did not have it's own Repository)
}

这样我就可以在调用 http://127.0.0.1:8080/api/rest/Client/108?projection=inline 时在我的客户端 JSON 中嵌入省份:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  },
  "province" : {
    "name" : "Quebec"
  }
}

我发现我可以做到:

@Projection(name = "inline", types = { Client.class })
public interface ClientProjection {
    @Value("#{target}") 
    Client getClient();
    Province getProvince();  // This is the linked object I want to add to my json output as an in-line map (i.e have the behaviour as if it did not have it's own Repository)
}

但我将客户和省份都作为顶级元素。即省份不在客户端中:

{
  "province" : {
    "name" : "quebec"
  },
  "client" : {
      "nom" : "Mallowpond High",
      "adresseLigne1" : "895 Gonçal Burg",
      "adresseLigne2" : "Apt. 450",
      "ville" : "Lake Irenehaven",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8080/api/rest/Client/108"
        },
        "province" : {
          "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
        }
      }
  }
}

您的 @RestRepositoryResource 生成的称为 HAL 格式。您的要求与 HAL 的规范有所不同,我建议您遵守标准(出于显而易见的原因)。

在 HAL 中,支持将关系嵌入到资源中。这意味着您最终会得到一个 _embedded 字段,该字段将包含基数 1 和其中的省份的集合。那看起来像这样:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  },
  "_embedded"{
     "provinces" : [{
        "name" : "Quebec",
        "_links" : {
          "self" : {
            "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
          }
        }
     }]
  }
}

不幸的是,Spring 的 @RepositoryRestResource 并不容易支持这一点,但仍然相对容易实现。您需要添加一个 ResourceAssembler 并将 Client 转换为支持 _embedded 字段的 ClientResource。看看 this question 如何做到这一点(我自己也用这个)