Как я могу интернационализировать ошибки API в Spring Boot? - PullRequest
0 голосов
/ 14 мая 2019

Мне удалось интернационализировать запрос веб-страницы контроллера с помощью

@RequestMapping(value="/image")
public String image(@RequestHeader(name=HEADER_CONSTANTS.ACCEPT_LANGUAGE, required=false) String al) {

В списке параметров. Однако я попытался поместить это в ResponseEntityExceptionHandler, и это не сработало.

@ControllerAdvice(basePackages="com.example.apis")
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(ApiException.class)
    protected ResponseEntity<Object> handleApiException(ApiException ex, @RequestHeader(name=HEADER_CONSTANTS.ACCEPT_LANGUAGE, required=false) String al) {

2019-05-13 21: 59: 59.193 ПРЕДУПРЕЖДЕНИЕ 16052 --- [nio-8080-exec-1] .mmaExceptionHandlerExceptionResolver: не удалось вызвать метод @ExceptionHandler: protected org.springframework.http.ResponseEntity com.example. apis.RestExceptionHandler.handleApiException (com.example.apis.ApiException, java.lang.String)

java.lang.IllegalStateException: не удалось разрешить параметр метода по индексу 1 в защищенном org.springframework.http.ResponseEntity com.example.apis.RestExceptionHandler.handleApiException (com.example.apis.ApiException, java.lang.String) : Нет подходящего преобразователя для аргумента 1 типа 'java.lang.String'

Работает без параметра @RequestHeader. Как я могу получить клиентский HTTP-заголовок Accept-Language в обработчике исключений для запросов JSON API?

Spring Boot 1.5.20

Ответы [ 3 ]

1 голос
/ 14 мая 2019

Если вам нужна локаль текущего пользователя, вы должны зарегистрировать LocaleResolver и затем получить локаль из LocaleContextHolder.

@Bean
public LocaleResolver localeResolver() {
    // Registering accept-header Locale Resolver with default Locale.US
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setDefaultLocale(Locale.US);

    return localeResolver;
}

Затем вы можете получить локаль в вашем обработчике исключений, вызвав LocaleContextHolder.getLocale().

0 голосов
/ 14 мая 2019

Я использовал следующее, основываясь на ответе Дэдпула.Я получил исключения (org.springframework.context.NoSuchMessageException), если языковой пакет не содержал перевода для данного ключа сообщения.Хотелось бы, чтобы по умолчанию был английский, если файл .properties не содержит перевода, в одну строку.

@ExceptionHandler(ApiException.class)
protected ResponseEntity<Object> handleApiException(ApiException ex, Locale locale) {
    String defaultMessage = messages.getMessage(ex.errorMessage, ex.errorArgument, Locale.ENGLISH);
    String localErrorMessage = messages.getMessage(ex.errorMessage, ex.errorArgument, defaultMessage, locale);
0 голосов
/ 14 мая 2019

Документация для @ ExceptionHandler

Недопустимый синтаксис, посмотрите правила подписей методов.Вы можете использовать WebRequest, чтобы получить аннотацию Header

@ExceptionHandler(ApiException.class)
protected ResponseEntity<Object> handleApiException(ApiException ex, WebRequest request) {
     request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
}

для обработки исключений в определенных классах обработчиков и / или методах обработчиков.

Методы-обработчики, аннотированные этой аннотацией,разрешено иметь очень гибкие подписи.Они могут иметь параметры следующих типов в произвольном порядке:

  • Аргумент исключения: объявлен как общее исключение или как более конкретное исключение.Это также служит подсказкой для отображения, если сама аннотация не сужает типы исключений с помощью своего значения ().

  • Объекты запросов и / или ответов (обычно из API сервлета).Вы можете выбрать любой конкретный тип запроса / ответа, например, ServletRequest / HttpServletRequest.

  • Объект сеанса: обычно HttpSession.Аргумент этого типа обеспечит наличие соответствующего сеанса.Как следствие, такой аргумент никогда не будет нулевым.Обратите внимание, что доступ к сеансу может не быть потокобезопасным, в частности в среде сервлетов: рассмотрите возможность переключения флага «synchronizeOnSession» на «true», если нескольким запросам разрешен одновременный доступ к сеансу.

  • WebRequest или NativeWebRequest.Разрешает общий доступ к параметрам запроса, а также доступ к атрибуту запроса / сеанса без привязки к собственному сервлетному API.

  • Языковой стандарт для текущего языкового стандарта запроса (определяется самым конкретным из доступных преобразователей языковых стандартов, т.е. настроенный LocaleResolver в среде сервлета).InputStream / Reader для доступа к содержимому запроса.Это будет необработанный InputStream / Reader, предоставляемый Servlet API.

  • OutputStream / Writer для генерации содержимого ответа.Это будет необработанный OutputStream / Writer, предоставляемый Servlet API.

  • Модель в качестве альтернативы возвращению карты модели из метода обработчика.Обратите внимание, что предоставленная модель предварительно не заполняется обычными атрибутами модели и, следовательно, всегда пуста, что удобно для подготовки модели для представления, специфичного для исключения

...