我正在尝试对名为Institute
的实体类应用投影。
我定义了以下投影类。
@Projection(name = "instituteProjection", types = { Institute.class })
public interface InstituteProjection {
String getOrganizationName();
Contact getContact();
Address getRegisteredAddress();
Address getMailingAddress();
}
我遵循了Oliver Gierke link的回答,并且能够在调用http://localhost:8080/institutes
时返回带有投影的收集资源。我通过在服务层中实现以下方法然后使用REST控制器调用它来完成此操作。
@Autowired
private ProjectionFactory projectionFactory;
@Autowired
InstituteTypeRepository instituteTypeRepo;
@Override
public PagedResources<Institute> getAllInstitutes(Pageable page) {
Page<?> instituteList = instituteRepo.findAll(page).
map(institute -> projectionFactory.createProjection(InstituteListProjection.class, institute));
PagedResources<Institute> instituteListPaged = pagedResourcesAssembler.toResource(instituteList);
return instituteListPaged;
}
现在,当调用http://localhost:8080/institutes/1
时,如何将相同的投影应用于项目资源?
更新1:
获取单一资源的控制器方法
@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
Institute institute = service.getInstitute(instituteId);
return new ResponseEntity<>(institute, HttpStatus.OK);
}
更新2:
从存储库中获取单个资源的服务层方法
@Override
public Institute getInstitute(Long instituteId) {
Institute institute = instituteRepo.findOne(instituteId);
return institute;
}
答案 0 :(得分:1)
你的问题有点不清楚。您可以自动将Spring Data存储库作为其他资源公开,即您不需要定义自己的Spring MVC控制器。
http://docs.spring.io/spring-data/rest/docs/current/reference/html/#install-chapter
使用SDR存储库,预测被定义为&#39;摘录预测&#39;可以自动应用于收集资源:
http://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts.excerpts
但不是单一资源。对于单个资源,客户端必须通过请求参数指定所需的投影。
如果您希望将投影自动应用于单个资源,那么这可能是实施您自己的控制器的原因(但是,您的问题是否与您正在进行的操作无关)。
对于自动将投影应用于单个资源的替代方法(即没有自定义控制器,请参见此处):
Spring Data REST: projection representation of single resource
如果要创建自定义控制器以自动应用投影,则可以简单地编写返回投影而不是完整实体的自定义查询方法,并从控制器/服务调用该方法:
基本上,通过一些配置,您可以选择自动公开为REST资源的Spring Data存储库,而无需编写任何控制器代码。
答案 1 :(得分:0)
在你的控制器或@RestController中你应该声明一个 @PathVariable 。也许该线程将为您服务:Spring mvc @PathVariable 因此,您使用路径变量解析实现控制器,然后使用 PathVariable 作为争论来调用您的服务
答案 2 :(得分:0)
在最新的 Spring Data Rest 版本中可以轻松完成!
您需要做的就是:
将投影名称作为请求参数传递
`/institutes/1?projection=instituteProjection`
从您的服务方法中返回 PersistentEntityResource
而不是 Institute
;
完成!
我假设您想从自定义控制器调用此服务方法,在这种情况下,您需要从控制器方法返回 ResponseEntity<PersistentEntityResource>
。
Spring Data Rest 负责在 api 请求上将 @Projection
应用到 PersistentEntityResource
,就像您不断从 @RestResource
中暴露 @RepositoryRestResource
一样;相同的投影行为,保持相同的命名约定,基本相同的 URI(对于当前示例)。
带有一些业务逻辑的服务方法可能如下所示:
@Override
@Transactional(readOnly = true)
public PersistentEntityResource getInstitute(Long instituteId, PersistentEntityResourceAssembler resourceAssembler) {
Institute institute = instituteRepo.findOne(instituteId);
return resourceAssembler.toModel(institute);
}
您的控制器方法可能如下所示:
@GetMapping(value = "institutes/{instituteId}")
ResponseEntity<PersistentEntityResource> getInstitute(@PathVariable Long instituteId,
PersistentEntityResourceAssembler resourceAssembler) {
return ResponseEntity.status(HttpStatus.OK)
.body(service.getInstitute(instituteId, resourceAssembler));
}
}
spring-data-rest 3.3.4.RELEASE
还可以查看更简单的方法to return a collection resource with the projections