如何国际化 Spring 引导中的 API 错误?
How do I internationalize API errors in Spring Boot?
我能够使用
将控制器网页请求国际化
@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] .m.m.a.ExceptionHandlerExceptionResolver : Failed to invoke @ExceptionHandler method: protected org.springframework.http.ResponseEntity com.example.apis.RestExceptionHandler.handleApiException(com.example.apis.ApiException,java.lang.String)
java.lang.IllegalStateException: Could not resolve method parameter at index 1 in protected org.springframework.http.ResponseEntity com.example.apis.RestExceptionHandler.handleApiException(com.example.apis.ApiException,java.lang.String): No suitable resolver for argument 1 of type 'java.lang.String'
它在没有 @RequestHeader
参数的情况下工作。如何在 JSON API 请求的异常处理程序中获取客户端的 Accept-Language
HTTP header?
Spring 引导 1.5.20
如果你需要的是当前用户的语言环境,你应该注册一个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()
.
在异常处理程序中获取语言环境
Documentation for @ExceptionHandler
语法无效,查看方法签名规则。您可以使用 WebRequest
来获取 Header
@ExceptionHandler(ApiException.class)
protected ResponseEntity<Object> handleApiException(ApiException ex, WebRequest request) {
request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
}
在特定处理程序中处理异常的注释 类 and/or 处理程序方法。
允许使用此注释注释的处理程序方法具有非常灵活的签名。它们可能具有以下类型的参数,顺序任意:
异常参数:声明为一般异常或更具体的异常。如果注释本身不通过其 value().
缩小异常类型,这也用作映射提示
请求and/or响应对象(通常来自ServletAPI)。您可以选择任何特定的 request/response 类型,例如ServletRequest / HttpServletRequest.
Session对象:典型的HttpSession。这种类型的参数将强制存在相应的会话。因此,这样的论点永远不会为空。请注意,会话访问可能不是 thread-safe,特别是在 Servlet 环境中:如果允许多个请求同时访问一个会话,请考虑将 "synchronizeOnSession" 标志切换为 "true"。
WebRequest 或 NativeWebRequest。允许通用请求参数访问以及 request/session 属性访问,与本机 Servlet API.
无关
当前请求区域设置的区域设置(由可用的最具体的区域设置解析器确定,即 Servlet 环境中配置的 LocaleResolver)。
InputStream / Reader 用于访问请求的内容。这将是 Servlet API.
公开的原始 InputStream/Reader
OutputStream / Writer 用于生成响应的内容。这将是 Servlet API.
公开的原始 OutputStream/Writer
模型作为从处理程序方法返回模型映射的替代方法。请注意,提供的模型 pre-populated 不具有常规模型属性,因此始终为空,以便于为 exception-specific 视图
准备模型
我根据 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);
我能够使用
将控制器网页请求国际化@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] .m.m.a.ExceptionHandlerExceptionResolver : Failed to invoke @ExceptionHandler method: protected org.springframework.http.ResponseEntity com.example.apis.RestExceptionHandler.handleApiException(com.example.apis.ApiException,java.lang.String)
java.lang.IllegalStateException: Could not resolve method parameter at index 1 in protected org.springframework.http.ResponseEntity com.example.apis.RestExceptionHandler.handleApiException(com.example.apis.ApiException,java.lang.String): No suitable resolver for argument 1 of type 'java.lang.String'
它在没有 @RequestHeader
参数的情况下工作。如何在 JSON API 请求的异常处理程序中获取客户端的 Accept-Language
HTTP header?
Spring 引导 1.5.20
如果你需要的是当前用户的语言环境,你应该注册一个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()
.
Documentation for @ExceptionHandler
语法无效,查看方法签名规则。您可以使用 WebRequest
来获取 Header
@ExceptionHandler(ApiException.class)
protected ResponseEntity<Object> handleApiException(ApiException ex, WebRequest request) {
request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
}
在特定处理程序中处理异常的注释 类 and/or 处理程序方法。
允许使用此注释注释的处理程序方法具有非常灵活的签名。它们可能具有以下类型的参数,顺序任意:
异常参数:声明为一般异常或更具体的异常。如果注释本身不通过其 value().
缩小异常类型,这也用作映射提示
请求and/or响应对象(通常来自ServletAPI)。您可以选择任何特定的 request/response 类型,例如ServletRequest / HttpServletRequest.
Session对象:典型的HttpSession。这种类型的参数将强制存在相应的会话。因此,这样的论点永远不会为空。请注意,会话访问可能不是 thread-safe,特别是在 Servlet 环境中:如果允许多个请求同时访问一个会话,请考虑将 "synchronizeOnSession" 标志切换为 "true"。
WebRequest 或 NativeWebRequest。允许通用请求参数访问以及 request/session 属性访问,与本机 Servlet API.
无关
当前请求区域设置的区域设置(由可用的最具体的区域设置解析器确定,即 Servlet 环境中配置的 LocaleResolver)。 InputStream / Reader 用于访问请求的内容。这将是 Servlet API.
公开的原始 InputStream/Reader
OutputStream / Writer 用于生成响应的内容。这将是 Servlet API.
公开的原始 OutputStream/Writer
模型作为从处理程序方法返回模型映射的替代方法。请注意,提供的模型 pre-populated 不具有常规模型属性,因此始终为空,以便于为 exception-specific 视图
准备模型
我根据 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);