2016-05-02 3 views
1

Мы используем весенний ботинок для нашего применения. Я пытаюсь вернуть локализованный результат в ответ при вызове службы Rest на основе заголовка Accept-Language. Например, если заголовок Accept-Language: zh, ja; q = 0,8, en. Так что ответ будет на китайском, так как мы поддерживаем это.Весенняя загрузка Исключение обработки

Но если заголовок Accept-Language: zh1, ja; q = 0.8, en. Затем я получаю ошибку внутреннего сервера, как показано ниже, потому что он не может вызывать @ExceptionHandler. Мне не нравится ответ. Ниже то, что я получаю

{ 
    "timestamp": 1462213062585, 
    "status": 500, 
    "error": "Internal Server Error", 
    "exception": "java.lang.IllegalArgumentException", 
    "message": "java.lang.IllegalArgumentException: range=zh1", 
    "path": "/user/v1//paymentmethods/creditdebitcards" 
} 

Вместо этого то, что я хочу бросить, потому что для всех других исключений мы обрабатываем и бросить подобный ответ.

{ 
    "operation": { 
    "result": "ERROR", 
    "errors": [ 
     { 
     "code": "1000", 
     "message": "An unidentified exception has occurred.", 
     "field": "" 
     } 
    ], 
    "requestTimeStampUtc": "2016-05-02T18:22:03.356Z", 
    "responseTimeStampUtc": "2016-05-02T18:22:03.359Z" 
    } 
} 

Ниже приведены мои классы, если заголовок не так (как ZH1, JA; д = 0,8, еп), то метод синтаксического анализа ниже выбрасывает ошибку 500, как и выше.

public class SmartLocaleResolver extends AcceptHeaderLocaleResolver { 

    @Autowired 
    ExceptionHandling exceptionHandling; 

    @Autowired 
    MessageHandler messageHandler; 

    @Override 
    public Locale resolveLocale(HttpServletRequest request) { 
     try { 
      List<LanguageRange> list = Locale.LanguageRange.parse(request.getHeader("Accept-Language")); 
      if (!list.isEmpty()) { 
       for (LanguageRange s : list) { 
        if (ApplicationConstants.LOCALE.contains(s.getRange())) { 
         return Locale.forLanguageTag(s.getRange()); 
        } 
       } 
      } 
     } catch (IllegalArgumentException e) { 
      throw new IllegalArgumentException(e); 
     } 
     return request.getLocale(); 
    } 

Ниже класс ExceptionHandler

@EnableWebMvc 
@ControllerAdvice 
public class ExceptionHandling extends ResponseEntityExceptionHandler { 
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandling.class); 

    @Autowired 
    private MessageHandler  messageHandler; 

    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) 
    @ExceptionHandler(value = { UnsupportedMediaTypeException.class, InvalidMediaTypeException.class }) 
    public void unsupportedMediaTypeException() { 

    } 

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 
    @ExceptionHandler(value = Exception.class) 
    public @ResponseBody OperationsErrorBean handleglobalException(final HttpServletRequest request, 
      final Exception ex) { 
     LOGGER.error("Unhandled Exception Occurred: ", ex); 
     return errorResponse("1000", messageHandler.localizeErrorMessage("error.1000"), "", request.getRequestURI(), 
       request.getAttribute("startTime").toString()); 

    } 
} 

Это мой класс ApplicationConfig.java

@Configuration 
@ComponentScan("com.hsf") 
@EnableWebMvc 
public class ApplicationConfig extends WebMvcConfigurerAdapter { 

    @Value("${spring.application.name}") 
    String appName; 

    @Bean 
    public AlwaysSampler defaultSampler() { 
     return new AlwaysSampler(); 
    } 

    @Override 
    public void addInterceptors(final InterceptorRegistry registry) { 

     if (StringUtils.isNotBlank(appName)) { 
      MDC.put("AppName", appName); 

     } else { 
      MDC.put("AppName", "APPNAME_MISSING"); 
     } 

     registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/user/v1/**"); 
    } 

    @Bean 
    public LocaleResolver localeResolver() { 
     return new SmartLocaleResolver(); 
    } 

    @Bean 
    public DispatcherServlet dispatcherServlet() { 
     final DispatcherServlet servlet = new DispatcherServlet(); 
     servlet.setDispatchOptionsRequest(true); 
     return servlet; 
    } 

    @Bean 
    public MessageSource messageSource() { 
     final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); 
     messageSource.setBasenames("classpath:i18n/messages"); 
     // If true, the key of the message will be displayed if the key is not 
     // found, instead of throwing an exception 
     messageSource.setUseCodeAsDefaultMessage(true); 
     messageSource.setDefaultEncoding("UTF-8"); 
     // The value 0 means always reload the messages to be developer friendly 
     messageSource.setCacheSeconds(10); 
     return messageSource; 
    } 

} 
+0

Класс ExceptionHandling будет обрабатывать Exception.class, тогда как ваша программа вызывает IllegalArgumentException. Странно, как вы поймаете IllegalArugmentException, а затем новое то же исключение? Вы должны просто перебросить или не поймать его вообще. –

+0

@ExceptionHandler аннотации должны быть в состоянии обрабатывать список исключений? –

+0

@MinhKieu Я пробовал все из них, этот код в блоке catch в основном я пытаюсь изменить свой ответ. Я уже пробовал то, о чем вы уже упоминали. Это не вызывает никаких проблем. Проблема заключается в том, когда запрос был сделан, сначала он переходит в класс SmartLocalResolver, а затем вызывается класс ExceptionHander. Решение для моей проблемы - это класс ExceptionHandler, который нужно вызвать перед SmartLocalResolver. Но я не уверен, как на данный момент. – Arun

ответ

0

У меня есть проверка Accept-Language в перехватчике, и я бросаю настраиваемое исключение, которое я создал, когда возникает исключение, анализирующее заголовок. Поэтому я бросаю запрос 400 Bad с надлежащим ответом, который я хочу отобразить.

public class RequestInterceptor extends HandlerInterceptorAdapter { 
      @Override 
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
        throws Exception { 

       final String startTime = DateUtils.getUTCDate(); 

       request.setAttribute("startTime", startTime); 


       **try { 
        Locale.LanguageRange.parse(request.getHeader("Accept-Language")); 
       } catch (IllegalArgumentException e) { 
        throw new InvalidAcceptLanguageException(); 
       }** 

       return true; 

      } 
     } 

Я добавил метод в моем классе ExceptionHandling бросить InvalidAcceptLanguageException.

@EnableWebMvc 
@ControllerAdvice 
public class ExceptionHandling extends ResponseEntityExceptionHandler { 
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandling.class); 


    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    @ExceptionHandler(value = InvalidAcceptLanguageException.class) 
    @ResponseBody 
    public OperationsErrorBean invalidAcceptLanguageException(final HttpServletRequest request, final Exception ex) { 
     return errorResponse("N/A", "Accept-Language is not in correct format", "", request.getRequestURI(), 
       request.getAttribute("startTime").toString()); 
    } 
} 
3

@ExceptionHandler аннотаций для метода unsupportedMediaTypeException не содержит IllegalArgumentException, вместо:

@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) 
@ExceptionHandler(value = { UnsupportedMediaTypeException.class, 
    InvalidMediaTypeException.class }) 
public void unsupportedMediaTypeException() { } 

должна быть:

@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) 
@ExceptionHandler(value = { UnsupportedMediaTypeException.class, 
    InvalidMediaTypeException.class, IllegalArgumentException.class }) 
public void unsupportedMediaTypeException() { } 

Кроме того, так как кажется, обработка многочисленных языков является одним из требований вашего приложения, я предлагаю создать специальную RuntimeException для этой ситуации InvalidAcceptLanguageException вместо того, чтобы использовать общий IllegalArgumentException для этой цели ,

+0

Если я добавлю исключение IllegalArgumentException.класс, он дает мне статус 415 неподдерживаемого типа носителя, но в тот момент, когда я добавляю тело к этому методу unsupportedMediaTypeException(), чтобы получить значимый ответ, он говорит в журналах. Не удалось вызвать метод @ExceptionHandler. – Arun

+0

. Я добавил класс ApplicationConfig.java. Мое мышление заключается в том, что SmartLocaleResolver вызывается первым, а класс ExceptionHandling вызывается позже. Поэтому я не смог отменить ошибку 500 и изменить ответ. – Arun

Смежные вопросы