【发布时间】:2017-03-10 10:28:19
【问题描述】:
我有一个简单的UserRepository,它使用Spring Data REST 公开。
这是User 实体类:
@Document(collection = User.COLLECTION_NAME)
@Setter
@Getter
public class User extends Entity {
public static final String COLLECTION_NAME = "users";
private String name;
private String email;
private String password;
private Set<UserRole> roles = new HashSet<>(0);
}
我创建了一个UserProjection 类,其外观如下:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Projection(types = User.class)
public interface UserProjection {
String getId();
String getName();
String getEmail();
Set<UserRole> getRoles();
}
这是存储库类:
@RepositoryRestResource(collectionResourceRel = User.COLLECTION_NAME, path = RestPath.Users.ROOT,
excerptProjection = UserProjection.class)
public interface RestUserRepository extends MongoRepository<User, String> {
// Not exported operations
@RestResource(exported = false)
@Override
<S extends User> S insert(S entity);
@RestResource(exported = false)
@Override
<S extends User> S save(S entity);
@RestResource(exported = false)
@Override
<S extends User> List<S> save(Iterable<S> entites);
}
我还在配置中指定了用户投影以确保它会被使用。
config.getProjectionConfiguration().addProjection(UserProjection.class, User.class);
所以,当我在 /users 路径上执行 GET 时,我得到以下响应(应用了投影):
{
"_embedded" : {
"users" : [ {
"name" : "Yuriy Yunikov",
"id" : "5812193156aee116256a33d4",
"roles" : [ "USER", "ADMIN" ],
"email" : "yyunikov@gmail.com",
"points" : 0,
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8080/users/5812193156aee116256a33d4"
},
"user" : {
"href" : "http://127.0.0.1:8080/users/5812193156aee116256a33d4{?projection}",
"templated" : true
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8080/users"
},
"profile" : {
"href" : "http://127.0.0.1:8080/profile/users"
}
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
但是,当我尝试对单个资源进行 GET 调用时,例如/users/5812193156aee116256a33d4,我收到以下回复:
{
"name" : "Yuriy Yunikov",
"email" : "yyunikov@gmail.com",
"password" : "123456",
"roles" : [ "USER", "ADMIN" ],
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8080/users/5812193156aee116256a33d4"
},
"user" : {
"href" : "http://127.0.0.1:8080/users/5812193156aee116256a33d4{?projection}",
"templated" : true
}
}
}
如您所见,密码字段正在返回并且未应用投影。我知道有@JsonIgnore 注释可以用来隐藏资源的敏感数据。但是,我的 User 对象位于不了解 API 或 JSON 表示的不同应用程序模块中,因此在那里用 @JsonIgnore 注释标记字段是没有意义的。
我看过@Oliver Gierke here 的帖子,关于为什么摘录投影不会自动应用于单个资源。但是,就我而言,这仍然很不方便,我想在获得单个资源时返回相同的UserProjection。是否有可能在不创建自定义控制器或使用@JsonIgnore 标记字段的情况下做到这一点?
【问题讨论】:
-
您可以使用
ResourceProcessor来完成此操作(或类似效果)。在 jira.spring.io/browse/DATAREST-428jira.spring.io/browse/DATAREST-428 的 cmets 中有一些可能有用的讨论 -
@CollinD 感谢您提供出色的链接!似乎
ResourceProcessor或ResourceAssembler的解决方案适合这种情况。但是我仍然想知道为什么 Spring Data REST 中没有任何注释或配置。 -
ResourceProcessor 现在是 RepresentationModelProcessor:stackoverflow.com/a/56126713/11451863
标签: spring rest spring-data spring-data-rest spring-hateoas