我正在使用Spring boot 1.5.3,Spring Data REST,Spring HATEOAS。 Spring Data REST非常棒,并且做得很好,但有时它需要自定义业务逻辑,因此我需要创建一个自定义控制器。
我将使用@RepositoryRestController来受益于Spring Data REST功能(http://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.overriding-sdr-response-handlers)。
因为Spring Data REST默认使用HATEOAS,所以我正在使用它。我需要一个像这样的控制器:
@RepositoryRestController
@RequestMapping(path = "/api/v1/workSessions")
public class WorkSessionController {
@Autowired
private EntityLinks entityLinks;
@Autowired
private WorkSessionRepository workSessionRepository;
@Autowired
private UserRepository userRepository;
@PreAuthorize("isAuthenticated()")
@RequestMapping(method = RequestMethod.POST, path = "/start")
public ResponseEntity<?> start(@RequestBody(required = true) CheckPoint checkPoint) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (checkPoint == null) {
throw new RuntimeException("Checkpoint cannot be empty");
}
if (workSessionRepository.findByAgentUsernameAndEndDateIsNull(auth.getName()).size() > 0) {
// TODO return exception
throw new RuntimeException("Exist a open work session for the user {0}");
}
// ...otherwise it's opened a new work session
WorkSession workSession = new WorkSession();
workSession.setAgent(userRepository.findByUsername(auth.getName()));
workSession.setCheckPoint(checkPoint);
workSession = workSessionRepository.save(workSession);
Resource<WorkSession> resource = new Resource<>(workSession);
resource.add(entityLinks.linkFor(WorkSession.class).slash(workSession.getId()).withSelfRel());
return ResponseEntity.ok(resource);
}
}
因为参数CheckPoint必须是一个存在的资源,我希望客户端发送资源的链接(就像你可以在Spring Data REST POST方法中那样)。 不幸的是,当我尝试这样做时,服务器端我收到一个空的CheckPoint对象。
我已阅读Resolving entity URI in custom controller (Spring HATEOAS)和converting URI to entity with custom controller in spring data rest?,特别是Accepting a Spring Data REST URI in custom controller。
我想知道是否有一种最佳做法可以避免向客户端公开id,请遵循HATEOAS原则。
答案 0 :(得分:1)
尝试改变你的控制器:
@RepositoryRestController
@RequestMapping(path = "/checkPoints")
public class CheckPointController {
//...
@Transactional
@PostMapping("/{id}/start")
public ResponseEntity<?> startWorkSession(@PathVariable("id") CheckPoint checkPoint) {
//...
}
}
这意味着:&#34;对于具有给定ID的CheckPoint,启动新的WorkSession&#34;。
您的POST请求将类似于:localhost:8080/api/v1/checkPoints/1/start
。