- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 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 错误那样得到处理。对于上下文,FrameworkServlet
由 DispatcherServlet
扩展,它覆盖 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/
是否可以使用应用程序名称的值(自动)设置cookiePath?例如,我有一个 test.war,因此它将在 bla.com/test/上提供,所以我希望我的 cookie 路径为 /test/ 而不是
我有两个文件用于我要翻译的文本: messages_es_ES.propertiesmessages_en_US.properties 我正在使用 CookieLocaleResolver: @Bea
我想首先通过检测 cookie 来解析用户的语言环境,如果没有,则通过接受语言 header 来解析。 Spring 似乎只想接受一个 LocaleResolver。 有趣的是,CookieLocal
我有一个 Spring Boot 应用程序,它具有用于语言环境解析器的 org.springframework.web.servlet.i18n.CookieLocaleResolver。如果存在像
在 web.xml 中: contextConfigLocation /WEB-INF/applicationContext*.xml org.springframewo
我是一名优秀的程序员,十分优秀!