gpt4 book ai didi

spring-boot - 带有 CookieLocaleResolver 的 Spring Boot 应用程序中的错误页面

转载 作者:行者123 更新时间:2023-12-04 02:29:37 24 4
gpt4 key购买 nike

我有一个 Spring Boot 应用程序,它具有用于语言环境解析器的 org.springframework.web.servlet.i18n.CookieLocaleResolver。如果存在像 !en 这样的无效语言 cookie,那么将出现异常 java.lang.IllegalArgumentException: Locale part "!en"包含无效字符

问题是这个异常没有被 Spring Boot 处理,而是被转发到 Servlet 容器。所以显示容器的默认错误页面(在我的例子中是 JBoss EAP 6),它将显示堆栈跟踪。

来自 Controller 的其他异常已得到妥善处理。例如,我有一个 Controller 映射,它会抛出 /by zero error 并得到正确处理。

我试过在 web.xml 中配置错误页面如下。

<error-page>
<location>/500</location>
</error-page>

并将 /error/500 映射到 MVC Controller ,如下所示。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.AbstractErrorController;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class CustomErrorController extends AbstractErrorController {
public static final String ERROR_500 = "/500";
private static final String ERROR_PATH= "/error";

@Autowired
public CustomErrorController(ErrorAttributes errorAttributes) {
super(errorAttributes);
}


/**
* Responsible for handling all errors and throw especial exceptions
* for some HTTP status codes. Otherwise, it will return a map that
* ultimately will be converted to a json error.
*/
@RequestMapping({ERROR_PATH,ERROR_500})
public ResponseEntity<?> handleErrors(HttpServletRequest request) {
return ResponseEntity.status(getStatus(request)).body(getErrorAttributes(request, false));
}

@Override
public String getErrorPath() {
return ERROR_PATH;
}
}

但我仍然收到容器的默认错误页面。如何解决这个问题。

最佳答案

处理请求的 FrameworkServlet 在通过调度程序发送请求之前确定 Locale,因为解析 Locale 时抛出的异常不会在 processDispatchResult< 中被捕获 因此不会像普通的 WebMvc 错误那样得到处理。对于上下文,FrameworkServletDispatcherServlet 扩展,它覆盖 buildLocaleContext(request) 并依次调用 CookieLocaleResolver 实例。

/**
* Process this request, publishing an event regardless of the outcome.
* <p>The actual event handling is performed by the abstract
* {@link #doService} template method.
*/
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

long startTime = System.currentTimeMillis();
Throwable failureCause = null;

// Here the locale is determined
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = buildLocaleContext(request);

RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

initContextHolders(request, localeContext, requestAttributes);

try {
// here is where the WebMvc processing happens
doService(request, response);
}
catch (ServletException ex) {
failureCause = ex;
throw ex;
}
catch (IOException ex) {
failureCause = ex;
throw ex;
}
catch (Throwable ex) {
failureCause = ex;
throw new NestedServletException("Request processing failed", ex);
}

finally {
resetContextHolders(request, previousLocaleContext, previousAttributes);
if (requestAttributes != null) {
requestAttributes.requestCompleted();
}

if (logger.isDebugEnabled()) {
if (failureCause != null) {
this.logger.debug("Could not complete request", failureCause);
}
else {
if (asyncManager.isConcurrentHandlingStarted()) {
logger.debug("Leaving response open for concurrent processing");
}
else {
this.logger.debug("Successfully completed request");
}
}
}

publishRequestHandledEvent(request, response, startTime, failureCause);
}
}

buildLocaleContext() 的 DispatcherServlet 方法

/**
* Build a LocaleContext for the given request, exposing the request's primary locale as current locale.
* <p>The default implementation uses the dispatcher's LocaleResolver to obtain the current locale,
* which might change during a request.
* @param request current HTTP request
* @return the corresponding LocaleContext
*/
@Override
protected LocaleContext buildLocaleContext(final HttpServletRequest request) {
if (this.localeResolver instanceof LocaleContextResolver) {
return ((LocaleContextResolver) this.localeResolver).resolveLocaleContext(request);
}
else {
return new LocaleContext() {
@Override
public Locale getLocale() {
return localeResolver.resolveLocale(request);
}
};
}
}

关于spring-boot - 带有 CookieLocaleResolver 的 Spring Boot 应用程序中的错误页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39061360/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com