排除 Spring-data-rest 资源的某些字段

我正在尝试将Spring-data-rest与spring-data-mongodb一起使用来公开只读资源。

我遇到的问题是,我想对我的文档有不同的看法。假设我在文档中有一些私人信息,我不想公开它们。

所以我尝试了几种方法。我阅读了这篇文章 https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring 描述了如何使用JsonView来选择要公开的字段。

我试过这样:

@RepositoryRestResource(collectionResourceRel = "recommandation", path =    "recommandations")
interface RecommandationRepository extends MongoRepository<Recommendation,   ObjectId> {

@Override
@JsonView(View.Public.class)
Iterable<Recommendation> findAll(Iterable<ObjectId> objectIds);
... // other find methods
}

它不起作用。然而,在评论中说:https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring#comment-1725671983 答案建议使用@Projections但是@Projections导致这样的url:“.../recommandations{?projection}”这意味着投影只是一个选项,所以整个对象仍然暴露出来。

这里描述了另一种方法 https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path 它建议对我们不想公开的字段使用@RestResource(导出= false)注释。

但它并不灵活。如果我想公开一个公共只读API和一个私有完全访问API。无法为每个 api 禁用此注释。

还有其他建议吗?


答案 1

重要的一点是,Spring Data REST 使用基于域对象的 Jackson 序列化参数,而不是存储库定义。隐藏特定字段不出现在 JSON 中的一种简单方法如下:

@Entity
public class User {

    @Id @GeneratedValue
    private Long id;

    private String name;

    @JsonIgnore
    private String password;
    ...

在此示例中,无论如何使用此实体,我的 User 对象都不会导出密码字段。杰克逊支持要么把它放在场上,要么放在相应的getter方法上。

@JsonIgnore放入域模型中时,它使其成为默认定义。投影是用于更改呈现哪些字段的选项。请看以下示例:

@Projection(name = "noImages", types = {Item.class})
public interface NoImages {

    public Link getHtmlUrl();

}

此项目只能在呈现域对象时使用。它不是默认视图,而是通过 ?projection=noImages 使用的选项。但不要忘记:当需要应用 Jackson 序列化时,项目将覆盖域模型的设置。这意味着您可以为上面的 User 对象编写一个投影,并使其包含 String getPassword()。这将覆盖域模型的默认设置,进而导出密码。责任在你手中。

最后一件事。Spring Data REST支持摘录投影。最常见的用例是,您有一个与地址对象相关的 Customer 对象。默认情况下,查看客户地址的关系将显示要导航的 URI。但是,如果您一直需要地址信息,则可以通过创建呈现地址详细信息的投影来避免此额外的 GET 操作。然后,您可以为 Customer 对象配置该值,默认情况下启用此投影,并在获取客户记录时基本上内联地址详细信息。

我意识到参考文档在所有这些细节上都不是最新的。您可以跟踪我们的进度以适当地更新文档,如下所示:

还有一个错误,来自Spring Data REST的ALPS元数据还需要过滤掉标记有@JsonIgnore的域字段(请参阅 https://jira.spring.io/browse/DATAREST-463)

PS @RestResource已弃用,不是设置导出哪些字段的推荐方法。相反,请使用前面所示的@JsonIgnore


答案 2

根据@johannes-鲁道夫的建议...

请考虑将此设置应用于字段(如果从访问器映射,则应用属性):

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)    
private String password;

这将执行访问值的含义:将关联字段标记为只写。因此,可以设置该值,但不能通过 Jackson/JSON 序列化形式检索该值。


推荐