首页 > 解决方案 > Spring Boot 中休息控制器的 post 方法中的 b/w @ResponseStatus 和 ResponseEntity.created(location).build() 差异

问题描述

对于POSTRest 控制器中的方法,我想返回状态码 201。

我看到了两种方法。

第一个是:

    @PostMapping("/offers")
    @ResponseStatus(HttpStatus.CREATED)
    public Offer createOffer(@Valid @RequestBody Offer offer) {
        return offerRepository.Save(offer);
    }

第二种方法是:

   @PostMapping("/offers")
   public ResponseEntity<Object> createOffer(@Valid @RequestBody Offer offer) {
        return offerService.createOffer(offer);
    }

以下是我的服务类:

    @Override
    public ResponseEntity<Object> createOffer(Offer offer) {
         Offer uOffer=OfferRepository.save(offer);
         URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{jobTitle}").
                    buildAndExpand(uOffer.getJobTitle()).toUri();
         return ResponseEntity.created(location).build(); 
    }

所以我的问题是:对于第一种方法,我们没有使用任何方法ResponseEntity.created,因为我们只是@ResponseStatus(HttpStatus.CREATED)从控制器返回。但是在第二个我们没有使用@ResponseStatus(HttpStatus.CREATED),我们正在通过使用 uri 和响应实体来处理状态代码 201。

两种方法有什么区别?两者似乎相同,因为它们返回相同的响应代码 201。首选哪一个?

标签: springspring-bootmodel-view-controller

解决方案


在我看来,您应该应用以下规则。如果你想返回一个 ResponseEntity 然后用它来影响状态。因此类似于:

@PostMapping("/offers")
public ResponseEntity<Offer> createOffer(@Valid @RequestBody Offer offer) {
     Offer offer = offerService.createOffer(offer);
     URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{jobTitle}").
                buildAndExpand(uOffer.getJobTitle()).toUri();
     return ResponseEntity.created(location)
                          .body(offer)
                          .build(); 
}

不要让您的服务生成 ResponseEntity,因为这是控制器的视图类,不应该在服务中。

第二种选择是使用类而不是响应实体。那么这个例子将是这样的:

@PostMapping("/offers")
@ResponseStatus(HttpStatus.CREATED)
public Offer createOffer(@Valid @RequestBody Offer offer) {
     // Do not return response entity but the offer
     return offerService.createOffer(offer);
}

推荐阅读