Closed mr-pachev closed 4 months ago
Привет, мистър Пачев! :-)
Свалих hrm-users, там нямаше много контролери, но разбирам въпроса ти. :-)
Наскоро имахме подобно чудене и ще ти кажа горе долу как подходихме (част от кода е на котлин както и ще скрия част от него заради "legal issues", но мисля че няма да е голям проблем това).
Постановка:
POST заявка, която не може да мине заради някакво условие на сървъра (например в твоя случай това е вече съществуващ юзър).
Как го направихме. На сървъра:
Например един custom Exception със няколко кода за грешки, напр:
class XXXConflictException(message: String, val errorCode: ErrorCode) : RuntimeException(message) {
enum class ErrorCode {
CODE1,
CODE2,
CODE3
}
}
Тук XXX
и CODE1-CODE3
са реално с други имена в нашия проект и съответстват на няколко вида потенциални грешки които само сървъра може да установи.
Този custom exception се хвърля на сървъра когато усетим че има проблем (например, в твоя случай - съществува user). Прихваща се с глобален (или локален) exception handler, например:
@ControllerAdvice
class GlobalExceptionHandlers {
@ExceptionHandler(XXXConflictException::class)
@ResponseBody
@ResponseStatus(HttpStatus.CONFLICT)
fun handleXXXConflictException(exception: XXXConflictException): ApiErrorDTO {
return ApiErrorDTO(
timestamp = LocalDateTime.now(),
status = HttpStatus.CONFLICT.value(),
error = HttpStatus.CONFLICT.reasonPhrase,
errorCode = exception.errorCode.name
)
}
}
ApiErrorDTO
e къстъм отговор за грешка, нормално DTO което съдържа код на грешката.
На клиента (при нас е андроид клиент, а не е спринг приложение, затова показвам едно примерче за обработка на статус конфликт):
offerRestClient
.get()
.uri("/offers..")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(
s -> s.isSameCodeAs(HttpStatus.CONFLICT),
(req, resp) -> {
// convert response to cusom object
ErrorDTO errorDTO = objectMapper.readValue(resp.getBody(), ErrorDTO.class);
throw new YourException(errorDTO.errorCode());
}
)
.body(new ParameterizedTypeReference<>(){});
Хвърляш подходящ YourException
, където си запазил конкретния код на грешката идващ от сървъра и го обработваш с глобален/локален exception handler или пък дори try/catch.
BTW в документацията на спринг е много философски споменато как да създадем DTO от response в по-сложните случаи :-) Много са гадни понякога.
По-лесни варианти за решение:
По-трудните варианти ги бяхме опитали в минали години, с PathFinder. Виж тук и съответния exception handler на ред 68. За съжаление, клиента е JS.
Поздрави, Л.
Благодаря за изчерпателният отговор. Надявам се да успея да приложа част от нещата, които ме посъветва.
Попълнете отделните секции отдолу и изтрийте упътванията.
Връзка към проекта: Human Resource Managements - Rest Client -https://github.com/mr-pachev/human-resource-managements.git HRM-Users - Rest Server - https://github.com/mr-pachev/hrm-users.git
Кратко описание -> Верификация на данните при регистрация на нов потребител. Не знам как да направя заявка към Rest Server-а и съответно как да проверя отговора в Rest Client-a, дали изпратеният обект е записан или вече съществува такъв.
Операция -> създаване на нов потребител.
Стъпки -> минала проверка на за валидация на полетата от формата, направена проверка дали въведените пароли в полетата password и confirm password са едентични, булев отговор от сървиса дали потребителя е създаден (направена проверка дали вече съществува потребител)
Опишете възможно най-лесните стъпки, с помощта на които бързо може да се репродуцира проблемът.
връщане на булев резултат в контролера на Rest Client-а, за да изпише на страницата или не, съобщение, че потребителя съществува вече
Благодаря предварително ако все пак имаш възможност да поразгледаш какви съм ги сътворил.