Spring ResponseEntity для опций

В своем коде я часто использую следующую конструкцию:

@RestController
public class HelloController {
  @Autowired
  private HelloService helloService;

  @GetMapping("/hello")
  ResponseEntity<Message> getHelloMessage() {
    Optional<Message> message = helloService.getMessage();
    if (message.isPresent()) {
      return ResponseEntity.ok(message.get());
    }
    return new ResponseEntity(HttpStatus.NO_CONTENT);
  }
}

Следуя принципам DRY, я абстрагирую эту конструкцию с помощью:

private <T> ResponseEntity<T> response(Optional<T> value) {
  if (value.isPresent()) {
    return ResponseEntity.ok(value.get());
  }
  return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

Так что мой код становится;

  @GetMapping("/hello")
  ResponseEntity<Message> getHelloMessage() {
    return response(helloService.getMessage());
  }

Было бы очень хорошо, если бы эта конструкция была частью класса ResponseEntity из spring, чтобы мой код стал;

 @GetMapping("/hello")
 ResponseEntity<Message> getHelloMessage() {
   return ResponseEntity.optional(helloService.getMessage());
 }

Как вы думаете, стоит ли реализовать такой метод в ResponseEntity?

Какой точный вопрос

Ajit Soman 06.07.2018 12:28

Я не понимаю, о чем вы спрашиваете. Но на мой взгляд, метод должен возвращать ожидаемый ответ. Если что-то случилось, то это следует обработать с помощью ExceptionHandler. Посмотрите: spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

KeyMaker00 06.07.2018 12:37

Я не сторонник исключения исключений только для того, чтобы получить ответ 204. Я предлагаю добавить в ResponseEntity удобный статический метод для обработки этих опций.

Rob Faber 06.07.2018 13:16

Я думаю, что все в порядке. иметь этот метод, но на самом деле вы не сэкономите много строк кода, имея его. Иногда я предпочитаю простоту ОСУШИВАНИЮ всего до смерти, то есть допустить небольшое повторение, если это полезно для понимания кода. Однако вы можете получить желаемую функциональность, используя другую зависимость: stackoverflow.com/questions/39978618/…

AlexLiesenfeld 06.07.2018 13:47
3
4
2 234
1

Ответы 1

Я знаю, что OP запросил ответ NO_CONTENT, но если вы после NOT_FOUND, вместо этого у вас есть удобный метод, начиная с Spring 5.1 - ResponseEntity.of():

 @GetMapping("/hello")
 ResponseEntity<Message> getHelloMessage() {
   return ResponseEntity.of(helloService.getMessage());
 }

Если вам нужен NO_CONTENT, могу я предложить следующее, немного менее подробное:

 @GetMapping("/hello")
 ResponseEntity<Message> getHelloMessage() {
        return helloService.getMessage()
                .map(ResponseEntity::ok)
                .orElseGet(() -> ResponseEntity.noContent().build());
 }

Другие вопросы по теме