#spring #spring-boot
#spring #весна-загрузка
Вопрос:
Учитывая этот код:
@GetMapping("/data/{id}")
public Data retrieveDataById(@PathVariable Long id) {
Optional<Data> data = dataService.findById(id);
if(data.isEmpty()){
return null;
}
else {
return data.get();
}
}
Основная проблема, я думаю, заключается в том, что null
возвращается, если элемент не найден.
Итак, вместо
if(data.isEmpty()){
return null;
}
Я планирую изменить его на:
if(data.isEmpty()){
ResponseEntity.ok("No records found for id" id);
}
Это правильно или есть другие изменения, которые я должен рассмотреть?
Обновить:
Изменение приводит к изменению возвращаемого типа с Data
на ResponseEntity
. Должен ли я добавить data.get();
в ResponseEntity
, если данные присутствуют? Изменение
Комментарии:
1. Использовать ResponseEntity — это нормально. Просто подумайте о коде состояния http
2. Не занимаясь весной в течение длительного времени, но
new ResponseEntity<String>("", HttpStatus.NOT_FOUND)
илиResponseEntity.notFound().build()
было бы лучше
Ответ №1:
Было бы лучше обернуть ответ при возврате с контроллеров
@GetMapping("/{id}")
public ResponseEntity<RoleDto> findById(@PathVariable String id) {
return ResponseEntity.ok(roleService.findById(id));
}
Для уровня обслуживания возврат пользовательского исключения с соответствующим сообщением об ошибке был бы более гибким при рассмотрении ситуации позже.
public RoleDto findById(String id) {
Optional<Role> role = roleRepository.findById(id);
return role.map(roleMapper::toDto).orElseThrow(() -> new ResourceNotFoundException(id, "Role not found"));
}
Пользовательское исключение может быть обработано в соответствии с требованиями конечного пользователя путем реализации @ControllerAdvice, уровня контроллера @ExceptionHandler или ResponseStatusException из Spring 5
Изменение приводит к изменению типа возвращаемого значения с Data на ResponseEntity. Должен ли я добавить data.get(); в ResponseEntity, если данные присутствуют? Изменение
Да, вы можете. Обычно вы можете выполнить эту операцию на уровне сервиса и вернуть DTO соответствующему контроллеру.
Ответ №2:
Необязательно дает вам возможность выполнять некоторые операции с его значением потоковым способом. Если вы разрабатываете конечные точки rest весной, вы могли бы либо вернуть ResponseEntity, как упоминал Joop Eggen, либо вы могли бы создать @ControllerAdivce и создать исключение, которое оно перехватило бы и отправило надлежащий статус http. С точки зрения масштабируемости, второй подход лучше, потому что вы можете использовать его с различными контроллерами.
Итак, первый случай:
@GetMapping("/data/{id}")
public ResponseEntityy<?> retrieveDataById(@PathVariable Long id) {
return dataService.findById(id)
.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
.orElse(ResponseEntity.notFound().build());
}
Второй случай:
@GetMapping("/data/{id}")
public Data retrieveDataById(@PathVariable Long id) {
return dataService.findById(id).orElseThrow(() -> new YourCustomRuntimeException());
}
@ControllerAdvice
class ControllerExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(YourCustomRuntimeException.class)
public ResponseEntity elementNotFound() {
return ResponseEntity.notFound().build();
}
}
Ответ №3:
если вы не хотите использовать ResponseEntity, вы также можете создать исключение ResponseStatusException, как показано здесь:https://www.baeldung.com/spring-response-status-exception#1-generate-responsestatusexception
Ответ №4:
Вы могли бы изменить его на like :
@GetMapping("/data/{id}")
public Data retrieveDataById(@PathVariable Long id) {
Optional<Data> data = dataService.findById(id);
if(data.isEmpty()){
return new ResponseEntity("No records found for id" id , HttpStatus.NOT_FOUND);
}
else {
return data.get();
}
}
Измените HttpStatus
код на 404, который указывает NOT FOUND
вместо возврата 200 в качестве кода состояния для этого сценария.