Java 排除 Spring-data-rest 资源的部分字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28322376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exclude some fields of Spring-data-rest resource
提问by Hugo Lassiège
I'm trying to use Spring-data-rest with spring-data-mongodb to expose read-only resources.
我正在尝试使用 Spring-data-rest 和 spring-data-mongodb 来公开只读资源。
The problem I met, is that I want to have different views of my documents. Let's say I have some private information in a document, I don't want to expose them publicly.
我遇到的问题是,我想对我的文档有不同的看法。假设我在文档中有一些私人信息,我不想公开它们。
So I tried several ways. I read this post https://spring.io/blog/2014/12/02/latest-Hymanson-integration-improvements-in-springdescribing how to use JsonView in order to select the fields we want to expose.
所以我尝试了几种方法。我读了这篇文章https://spring.io/blog/2014/12/02/latest-Hymanson-integration-improvements-in-spring描述了如何使用 JsonView 来选择我们想要公开的字段。
I've tried like this :
我试过这样:
@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
}
It doesn't works. It is however said in the comments : https://spring.io/blog/2014/12/02/latest-Hymanson-integration-improvements-in-spring#comment-1725671983The answer suggests to use @Projections However @Projections result in url like that : "…/recommandations{?projection}" It means that the projection is just an option, so the full object is still exposed.
它不起作用。然而,在评论中说:https://spring.io/blog/2014/12/02/latest-Hymanson-integration-improvements-in-spring#comment-1725671983 答案建议使用@Projections 但是@Projections 结果在这样的 url 中: ".../recommandations{?projection}" 这意味着投影只是一个选项,所以完整的对象仍然暴露。
There is another method described here https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-pathIt suggests to use @RestResource(exported = false) annotation for the fields we don't want to expose.
这里描述了另一种方法https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path它建议对字段使用@RestResource(exported = false) 注释我们不想暴露。
But it's not flexible. If I want to expose a public read-only API and a private full access API. This annotation can't be disabled per api.
但它不灵活。如果我想公开一个公共只读 API 和一个私有完全访问 API。不能为每个 api 禁用此注释。
Is there another suggestion ?
还有其他建议吗?
回答by gregturn
The important point is that Spring Data REST uses Hymanson serialization parameters based on the domain object, not the repository definition. One simple way to hide a particular field from appearing in the JSON is like this:
重要的一点是 Spring Data REST 使用基于域对象的 Hymanson 序列化参数,而不是存储库定义。隐藏特定字段不出现在 JSON 中的一种简单方法是这样的:
@Entity
public class User {
@Id @GeneratedValue
private Long id;
private String name;
@JsonIgnore
private String password;
...
In this example, my User object will NEVER export a password field no matter how this entity is used. Hymanson supports either putting this on the field, or putting on the corresponding getter method.
在此示例中,无论如何使用该实体,我的 User 对象都不会导出密码字段。Hymanson 支持将其放在现场,或者使用相应的 getter 方法。
When you put @JsonIgnorein the domain model, it makes it the default definition. Projections are options to alter what fields get rendered. Look at the following example:
当您将@JsonIgnore放入域模型时,它会使其成为默认定义。投影是改变渲染字段的选项。看下面的例子:
@Projection(name = "noImages", types = {Item.class})
public interface NoImages {
public Link getHtmlUrl();
}
This project can only be used when rendering Itemdomain objects. It isn't the default view, but instead an option to use via ?projection=noImages. But don't forget: when it comes time to apply Hymanson serialization, the project will override the domain model's settings. This means you can write a projection for that Userobject up above and have it include String getPassword(). This would override the domain model's default setting an in turn export a password. Responsibility is yours.
此项目只能在渲染Item域对象时使用。它不是默认视图,而是通过?projection=noImages使用的选项。但不要忘记:当需要应用 Hymanson 序列化时,项目将覆盖域模型的设置。这意味着您可以为上面的User对象编写一个投影,并让它包含String getPassword()。这将覆盖域模型的默认设置,进而导出密码。责任在你。
One last thing. Spring Data REST supports Excerpt Projections. The most common use case is where you have a Customerobject related to an Addressobject. By default, the relationship to see a customer's address would show a URI to navigate. But if you are wanting the address information all the time, you can avoid this extra GEToperation by creating a projection that renders the address details. Then you can configure that for Customerobjects, turn on this projection by default and essentially inline the address details whenever you fetch a customer record.
最后一件事。Spring Data REST 支持Excerpt Projections。最常见的用例是您有一个与Address对象相关的Customer对象。默认情况下,查看客户地址的关系将显示要导航的 URI。但是,如果您一直想要地址信息,则可以通过创建呈现地址详细信息的投影来避免这种额外的GET操作。然后,您可以为Customer对象配置它,默认情况下打开此投影,并在获取客户记录时基本上内联地址详细信息。
I realize the reference docs aren't quite up to date on all these details. You can track our progress to update the docs suitably as follows:
我意识到参考文档在所有这些细节上都不是最新的。您可以跟踪我们的进度以适当地更新文档,如下所示:
- https://jira.spring.io/browse/DATAREST-449
- https://jira.spring.io/browse/DATAREST-450
- https://jira.spring.io/browse/DATAREST-451
- https://jira.spring.io/browse/DATAREST-452
- https://jira.spring.io/browse/DATAREST-453
- https://jira.spring.io/browse/DATAREST-454
- https://jira.spring.io/browse/DATAREST-449
- https://jira.spring.io/browse/DATAREST-450
- https://jira.spring.io/browse/DATAREST-451
- https://jira.spring.io/browse/DATAREST-452
- https://jira.spring.io/browse/DATAREST-453
- https://jira.spring.io/browse/DATAREST-454
There is also a bug in that the ALPS metadata from Spring Data REST also needs to filter out domain fields tagged with @JsonIgnore(see https://jira.spring.io/browse/DATAREST-463)
还有一个错误是来自 Spring Data REST 的 ALPS 元数据也需要过滤掉标有@JsonIgnore 的域字段(参见https://jira.spring.io/browse/DATAREST-463)
P.S. @RestResourceis deprecated and not the recommended approach to setting what fields get exported. Instead, use @JsonIgnoreas shown earlier.
PS @RestResource已弃用,而不是设置导出哪些字段的推荐方法。相反,使用@JsonIgnore,如前面所示。
回答by sofend
Per @johannes-rudolph suggestion...
根据@johannes-rudolph 的建议...
Consider applying this setting to the field (or property if you're mapping from accessors):
考虑将此设置应用于字段(或属性,如果您从访问器映射):
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
This does what the access value implies: marking the associated field as write-only. Thus the value can be set but not retrieved via the Hymanson/JSON serialized form.
这就是访问值所暗示的:将关联字段标记为只写。因此,可以通过 Hymanson/JSON 序列化形式设置但不能检索该值。