C каким типом надо вызывать ResponseEntity?

У меня есть контроллер

@RestController
public class BookController {
    @GetMapping("/find-by-name/{name}")
    public ResponseEntity<BookEntity> findByName(@PathVariable String name) {
      ...

если имя найдено, то в этом методе я возвращаю

return  ResponseEntity.ok(book);

если нет, то

return new ResponseEntity("name= " + name + " not found", HttpStatus.NOT_ACCEPTABLE);

Все работает, но компилятор ругается:

Raw use of parameterized class 'ResponseEntity' 
Unchecked assignment: 'org.springframework.http.ResponseEntity' to 'org.springframework.http.ResponseEntity<BookEntity>' 
Unchecked call to 'ResponseEntity(T, HttpStatus)' as a member of raw type 'org.springframework.http.ResponseEntity' 

Попробовал сделать так (этот вариант нашел на сайте spring.io)

public ResponseEntity<?> findByName(@PathVariable String name) {
...
return new ResponseEntity<>("name= " + name + " not found", HttpStatus.NOT_ACCEPTABLE);

Та ошибка ушла, но теперь ругается на эту строку:

Generic wildcard types should not be used in return types

Код работает в обоих вариантах, но хотелось бы понять как все-таки это реализовать правильно.


Ответы (2 шт):

Автор решения: DeMmAge
return new ResponseEntity<>("name= " + name + " not found", HttpStatus.NOT_ACCEPTABLE);

Или

return new ResponseEntity<>(book, HttpStatus.OK);
→ Ссылка
Автор решения: Roman Konoval

Возвращать ResponseEntity<BookEntity> нельзя, т.к. метод у вас не всегда возвращает BookEntity. Поэтому получаете предупреждение компилятора, когда используете сырой тип (англ. raw type).

Правильно использовать ResponseEntity<?> или ResponseEntity<Object>.

Вот такой код компилируется без проблем:

public class A {

  public class BookEntity {
  }

  public ResponseEntity<?> findByName(String name) {
    if (!name.isEmpty()) {
      return new ResponseEntity<>(new BookEntity(), HttpStatus.OK);
    } else {
      return new ResponseEntity<>("", HttpStatus.NOT_FOUND);
    }
  }
}

но очевидно вы получаете предупреждения статического анализатора. В большинстве случаев использование неограниченного wildcard-а в возвращаемом типе плохо, т.к. это требует от клиента вашего кода анализировать реальный тип возвращаемого объекта в runtime.

В данном случае клиентом выступает spring и он поддерживает разные возвращаемые типы (т.к. spring не использует ваш метод статически, т.е. на этапе компиляции, а использует reflection и анализирует тип объекта уже на этапе выполнения). Так что в этом случае безопасно игнорировать это предупреждение (вы можете его отключить для метода если это возможно - зависит от инструмента, который вы используете).

Другой вариант - не использовать неограниченный wildcard. Т.е. использовать ResponseEntity<Object>.

И, немного не по теме, если объект не найден, то нужно возвращать http код 404 (not found), как в примере выше.

→ Ссылка