我有一个控制器来管理用户的POST
个工作。成功创建后,响应应包含创建的资源的链接。为此,我写了下面的ResourceAssembler
public class UserJobResourceAssembler implements ResourceAssembler<UserJob, Resource<UserJob>> {
private EntityLinks entityLinks;
public UserJobResourceAssembler(EntityLinks entityLinks) {
this.entityLinks = entityLinks;
}
@Override
public Resource<UserJob> toResource(UserJob entity) {
Resource<UserJob> resource = new Resource<>(entity);
resource.add(
entityLinks.linkToSingleResource(UserJob.class, entity.getId()).withSelfRel()
);
return resource;
}
}
这是控制器
@RequestMapping(value = "/profiles" )
@ExposesResourceFor(UserJob.class)
public class UserJobController {
private UserJobService userJobService;
public UserJobController(UserJobService userJobService) {
this.userJobService = userJobService;
}
@PostMapping(value = "/{uniqueId}/jobs")
public Resource<UserJob> createJob(@Valid @RequestBody UserJob userJob, final Principal principal, @PathVariable String uniqueId) {
return userJobService.save(userJob, principal.getName(), uniqueId);
}
@GetMapping(value = "/{uniqueId}" + JOBS + "/{jobId}")
@ResponseStatus(value = HttpStatus.CREATED)
public Resource<UserJob> getSingleJob(@PathVariable String uniqueId, @PathVariable String jobId) {
System.out.println("get single job for job id: " + jobId);
return new Resource<UserJob>(new UserJob());
}
}
uniqueId
是为其创建作业的用户的ID。
尽管ResourceAssembler
创建了链接,但链接错误。
"_links": {
"self": {
"href": "http://localhost:8085/api/v1/profiles/12"
}
}
我期望它是http://localhost:8085/api/v1/profiles/theCoder/jobs/12
我知道这不是ResourceAssembler
的问题,而是EntityLinks
的问题。这可以通过使用linkTo
而不是EntityLinks
resource.add(linkTo(methodOn(UserJobController.class).getSingleJob(entity.getUser().getUniqueId(), entity.getUserJobId().toString())).withSelfRel());
但是我想以DRY原理实现这一点,使用控制器类会使我将其设为DRY。
有哪些替代方案/解决方案?
答案 0 :(得分:2)
在资源处理器中,您正在将自身链接设置为UserJob(在控制器中设置的/ profiles)的URL,并连接id,因此它变为“ / profiles / id”。
如果您需要设置指向方法URL的链接,ControllerLinkBuilder是避免对URL进行硬编码的最佳选择(如果使用EntityLink,则需要这样做):
@PostMapping(value = "/{uniqueId}/jobs")
public Resource<UserJob> createJob(@Valid @RequestBody UserJob userJob, final Principal principal, @PathVariable String uniqueId) {
UserJob userJob = userJobService.save(userJob, principal.getName(), uniqueId);
return toResource(userJob);
}
private Resource<UserJob> toResource(UserJob userJob) {
Link selfLink = linkTo(methodOn(UserJobController.class)
.getSingleJob(/* values */))
.withSelfRel();
return new Resource<>(userJob, selfLink);
}