如何在Spring Boot中国际化API错误?

时间:2019-05-14 02:12:06

标签: java spring spring-boot internationalization spring-rest

我能够通过

使控制器网页请求国际化
@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 WARN 16052 --- [nio-8080-exec-1] .mmaExceptionHandlerExceptionResolver:无法调用@ExceptionHandler方法:受保护的org.springframework.http.ResponseEntity com.example。 apis.RestExceptionHandler.handleApiException(com.example.apis.ApiException,java.lang.String)

     

java.lang.IllegalStateException:无法解析受保护的org.springframework.http.ResponseEntity com.example.apis.RestExceptionHandler.handleApiException(com.example.apis.ApiException,java.lang.String)中索引1处的方法参数:对于类型'java.lang.String'的参数1没有合适的解析器

它不带@RequestHeader参数就可以工作。如何在JSON API请求的异常处理程序中获取客户端的Accept-Language HTTP标头?

Spring Boot 1.5.20

3 个答案:

答案 0 :(得分:1)

如果您需要的是当前用户的语言环境,则应注册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()在异常处理程序中获取语言环境。

答案 1 :(得分:0)

Documentation for @ExceptionHandler

这是无效的语法,请查看方法签名的规则。您可以使用WebRequest来获取Header

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

用于在特定处理程序类和/或处理程序方法中处理异常的注释。

带有此批注的

Handler方法允许具有非常灵活的签名。它们可能具有以下类型的参数,且顺序为任意

  • 一个异常参数:声明为一般Exception或更具体的异常。如果注释本身没有通过其value()缩小异常类型,这也可以作为映射提示。

  • 请求和/或响应对象(通常来自Servlet API)。您可以选择任何特定的请求/响应类型,例如ServletRequest / HttpServletRequest。

  • 会话对象:通常为HttpSession。这种类型的参数将强制相应会话的存在。结果,这样的参数将永远不会为空。请注意,会话访问可能不是线程安全的,尤其是在Servlet环境中:如果允许多个请求同时访问会话,请考虑将“ synchronizeOnSession”标志切换为“ true”。

  • WebRequest或NativeWebRequest。允许通用请求参数访问以及请求/会话属性访问,而无需与本地Servlet API绑定。

  • 当前请求语言环境的
  • 语言环境(由可用的最特定的语言环境解析器确定,即Servlet环境中配置的LocaleResolver)。 InputStream / Reader用于访问请求的内容。这将是Servlet API公开的原始InputStream / Reader。

  • OutputStream / Writer,用于生成响应的内容。这将是Servlet API公开的原始OutputStream / Writer。

  • Model作为从处理程序方法返回模型映射的替代方法。请注意,提供的模型未预先填充常规模型属性,因此始终为空,以方便为特定于异常的视图准备模型

答案 2 :(得分:0)

我根据Deadpool的回答使用了以下内容。如果语言包不包含给定消息键的翻译,我会遇到例外情况(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);