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

时间:2019-02-08 02:50:47

标签: java spring spring-data-rest spring-hateoas

给出给定类的投影,是否有办法告诉Spring包含在 Projection 批注的 types 中定义的类的所有默认属性? / p>

给出2个实体类

@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"
    }
  }
}

是否可以创建一种投影,该投影将返回 Client 的所有属性,而不必为 Client

中的所有属性编写所有getXXX方法>
@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"
        }
      }
  }
}

1 个答案:

答案 0 :(得分:0)

您的@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转换为支持ClientResource字段的_embedded。查看this question的操作方法(我自己也使用此方法)