2017-06-24 46 views
2

我正在使用Spring引導1.5.3,Spring Data REST,Spring HATEOAS。 Spring Data REST令人驚歎,並且完成了一項完美的工作,但有時需要定製業務邏輯,因此我需要創建一個定製控制器。春天如何解決@RepositoryRestController中的entity uri

我打算使用@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必須是existant資源,我想客戶端發送種質資源的鏈接(比如,你可以在Spring數據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,followind如此HATEOAS原則。

+0

請顯示您的POST請求的網址和正文。我認爲你應該通過CheckPoint ID作爲控制器方法的參數。 – Cepr0

+0

@ Cepr0這是網址:http:// localhost:8080/api/v1/workSessions/start,這是body {「checkPoint」:「http :// localhost:8080/api/v1/checkPoints/1「} – drenda

+0

查看我的回答... – Cepr0

回答

1

試圖改變你控制器是這樣的:

@RepositoryRestController 
@RequestMapping(path = "/checkPoints") 
public class CheckPointController { 

    //... 

    @Transactional 
    @PostMapping("/{id}/start") 
    public ResponseEntity<?> startWorkSession(@PathVariable("id") CheckPoint checkPoint) { 

     //...   
    } 
} 

這將意味着:「檢查點給定ID啓動新的分工作業」。 您的POST請求將如下所示:localhost:8080/api/v1/checkPoints/1/start

+0

我無法遵循第一個解決方案,因爲它不符合HATEOAS標準。我沒有資源的id,只是完整的UI(例如http:// localhost:8080/api/v1/checkPoints/1)。由於Jackson解串器異常,使用「容器」的第二個想法不起作用。我正在尋找遵循Spring的最佳實踐。 – drenda

+0

然後將您的控制器更改爲CheckPointController。我糾正了我的答案... – Cepr0

+1

對不起,也許我用錯誤的方式表達了自己。我正在嘗試一種方法來解決@RepositoryRestController中的實體URI,就像我在標題中寫的一樣。您的建議適用於特定情況,但如果我需要更多參數(實體),該怎麼辦?重點是:有一種方法來轉換uri - >實體。謝謝 – drenda