В настоящее время у меня есть базовое исключение DomainException с подклассами, такими как ExpiredOrderException.
Вариант 1. Не допускайте использования HTTP в домене
Исключения домена содержат только информацию о домене (код, аргументы, defaultMessage), а совет контроллера определяет статус HTTP:
Код: Выделить всё
public class DomainException extends RuntimeException {
private final String code;
private final Object[] args;
private final String defaultMessage;
public DomainException(String code, String defaultMessage, Object... args) {
super(defaultMessage);
this.code = code;
this.defaultMessage = defaultMessage;
this.args = args;
}
public String getCode() { return code; }
public String getDefaultMessage() { return defaultMessage; }
public Object[] getArgs() { return args; }
}
public class ExpiredOrderException extends DomainException {
public ExpiredOrderException(Object... args) {
super(
"error.order.expired",
"This order is already expired.",
args
);
}
}
@ExceptionHandler({
ExpiredOrderException.class
// add other domain exceptions here
})
public ResponseEntity
handleBadRequest(DomainException ex) {
Locale locale = LocaleContextHolder.getLocale();
String localizedMessage = messageSource.getMessage(
ex.getCode(),
ex.getArgs(),
ex.getDefaultMessage(),
locale
);
ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
pd.setTitle(ex.getCode());
pd.setDetail(localizedMessage);
pd.setProperty("args", ex.getArgs());
pd.setProperty("locale", locale.toLanguageTag());
return ResponseEntity.badRequest().body(pd);
}
Но возникает проблема со списком классов исключений.
Вариант 2. Поместите статус HTTP внутри исключения
Исключение домена содержит код состояния HTTP:
Код: Выделить всё
public class DomainException extends RuntimeException {
private final int httpCode;
private final String code;
private final Object[] args;
private final String defaultMessage;
public DomainException(int httpCode, String code, String defaultMessage, Object... args) {
super(code);
this.httpCode = httpCode;
this.code = code;
this.args = args;
this.defaultMessage = defaultMessage;
}
public int getHttpCode() { return httpCode; }
public String getCode() { return code; }
public String getDefaultMessage() { return defaultMessage; }
public Object[] getArgs() { return args; }
}
public class ExpiredOrderException extends DomainException {
public ExpiredOrderException(Object... args) {
super(400, "error.order.expired", "This order is already expired.", args);
}
}
@ExceptionHandler(DomainException.class)
public ProblemDetail handleDomainExceptions(DomainException ex) {
Locale locale = LocaleContextHolder.getLocale();
String localizedMessage = messageSource.getMessage(
ex.getCode(),
ex.getArgs(),
ex.getDefaultMessage(),
locale
);
ProblemDetail pd = ProblemDetail.forStatus(ex.getHttpCode());
pd.setTitle(ex.getCode());
pd.setDetail(localizedMessage);
return pd;
}
Мои вопросы
С точки зрения чистой архитектуры считается ли плохой практикой для исключений домена передавать коды состояния HTTP?
В целом, существует ли в Spring Boot рекомендуемый шаблон для сопоставления исключений домена с ответами HTTP?>
Подробнее здесь: https://stackoverflow.com/questions/798 ... -semantics
Мобильная версия