Обработване на изключения в Spring Boot приложение
Spring framework предлага на разработчиците няколко опции за обработка на изключения в техните приложения. Един от тях е global exception handler с анотации @ControllerAdvice и @ExceptionHandler.
При този вид обработка на изключения е необходимо да разпишете отделен клас, който да обработва всички изключения, които могат да бъдат хвърлени от приложението, на едно централно място:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception1.class)
public String handleException1() {
// handles exception type Exception1
}
@ExceptionHandler(Exception2.class)
public String handleException2() {
// handles exception type Exception2
}
// handlers for other exceptions...
}
Класът е анотиран с @ControllerAdvice, което е вид @Component. Той казва на Spring да прихване всички методи на обработка и да ги изпълни, когато бъдат хвърлени съответните изключения. В методите за обработване на изключения можете да регистрирате изключението, да пренасочите към удобни за потребителя страници за грешки, да промените кода на състоянието на отговора и всяка друга персонализирана логика, която искате да обработите, когато възникне съвпадащото изключение.
Пример:
CityService.java
@Service
public class CityService implements ICityService {
private final CityRepository cityRepository;
public CityService(CityRepository cityRepository) {
this.cityRepository = cityRepository;
}
@Override
public City findById(Long id) {
return cityRepository.findById(id)
.orElseThrow(() -> new CityNotFoundException(id));
}
}
CityNotFoundException.java
public class CityNotFoundException extends RuntimeException {
public CityNotFoundException(Long id) {
super(String.format("City with Id %d not found", id));
}
}
ControllerAdvisor.java
@ControllerAdvice
public class ControllerAdvisor extends ResponseEntityExceptionHandler {
@ExceptionHandler(CityNotFoundException.class)
public ResponseEntity<Object> handleCityNotFoundException(
CityNotFoundException ex, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "City not found");
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
}
}
CityController.java
@RestController
public class CityController {
private final ICityService cityService;
public CityController(ICityService cityService) {
this.cityService = cityService;
}
@GetMapping(value = "/cities/{id}")
public ResponseEntity<City> getCity(@PathVariable Long id) {
City city = cityService.findById(id);
return ResponseEntity.ok(city);
}
}