我有一个ErrorFilter
延长了弹簧GenericFilterBean
。如果发生某些错误,我想显示一个用tile装饰的错误页面。
有没有办法从过滤器设置视图名称?
<filter>
<filter-name>errorFilter</filter-name>
<filter-class>com.abc.filter.ErrorFilter</filter-class>
<init-param>
<param-name>errorPage</param-name>
<param-value>/jsp/errorpage.jsp</param-value>
</init-param>
</filter>
这是web.xml
中的配置,doFilter
中的errorfilter
方法如下:
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
StringBuffer reqUrl = httpReq.getRequestURL();
try {
chain.doFilter(req, resp);
} catch (Exception ex) {
String requestRepresentation = createRequestRepresentation(req);
errorService.handleException(reqUrl.toString(), ex, requestRepresentation);
req.getRequestDispatcher(
getFilterConfig().getInitParameter("errorPage")).forward(req, resp);
} catch (Error er) {
errorService.handleError(reqUrl.toString(), er);
req.getRequestDispatcher(
getFilterConfig().getInitParameter("errorPage")).forward(req, resp);
}
}
目前的错误没有用瓷砖装饰,所以我想用普通的页眉和页脚来装饰它,并从过滤器中调用该视图名称。
有可能吗?
编辑: 基本上我们希望能够做类似于Controller-method的事情,即返回“视图名称”;
已经尝试过:
答案 0 :(得分:1)
我认为这是不可能的,因为这是一个servlet过滤器,它将在应用spring请求映射器servlet之后应用。基本上,请求映射器servlet认为它已完成,并将请求传递回servlet容器。
视图名称仅适用于弹簧内部 - 在弹簧外部,在servlet容器中,您将不得不谈论网址,而不是视图名称。
重定向到特定网址会有效。为此,您必须了解重定向和转发之间的差异。
重定向将以下标头发送到客户端:
连同状态码301(永久重定向,让客户端知道它可以缓存此信息)或307(临时重定向,告诉客户端它应该再次询问,因为重定向可能会改变)
请求调度程序上的转发基本上模仿了一个新请求,您可以将请求发送到同一容器中的任何servlet。这意味着,您还必须考虑上下文路径,这意味着@iimuhin给出的答案:
response.sendRedirect(
request.getContextPath() +
getFilterConfig().getInitParameter("errorPage"));
实际上是正确的方法。您可以(应该)添加日志记录以查看实际发生的情况以及实际使用的路径。
也 - 你必须要注意缓冲。 servlet响应通常是缓冲的,在缓冲区已满或整个处理完成之前,不会向客户端发送任何内容。
刷新时,首先写入标题。这意味着在刷新响应之后更改标题是不可能的,因为它们已经被发送出去了。
这就是为什么servlet可以强制刷新的原因,但通常不应该这样做。
在您的情况下,您可能希望增加响应的缓冲区大小:
response.setBufferSize(int size)
在调用chain.doFilter()之前,以避免过早冲洗。
答案 1 :(得分:1)
为什么不使用spring的错误处理机制?这里有关于它的好帖子(带例子) - https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
除此之外,不确定是否有干净的方法。其他建议可能是调用您的应用程序来获取错误页面响应并替换响应输出(在这种情况下,您还需要使用&#34;缓冲&#34; http响应以确保流是尚未刷新)或重定向到错误网址。
答案 2 :(得分:1)
过滤器出现在Spring之前。可以使用ApplicationContextAware机制在Spring中注入Spring bean,但是形成Spring MVC视图意味着您必须在Filter中获取整个spring MVC框架。我认为这是不可能的,您必须使用RequestDispatcher转发请求,而不是转发到弹簧视图,而是转发到您自己的自定义视图。
答案 3 :(得分:0)
必须有一种方法可以使用Spring MVC,但我认为重定向就足够了。
try {
chain.doFilter(req, resp);
} catch (Exception ex) {
if (response.isCommitted()) {
log(ex); // at least a part of the response is already sent to the client, you can't do much about it
} else {
session.setAttribute("last.exception", ex);
response.sendRedirect(request.getContextPath() + getFilterConfig().getInitParameter("errorPage"));
}
}
P.S。不要发现错误!
答案 4 :(得分:0)
只需检查您的重定向网址即可。您可以使用网址访问页面。
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
throws IOException {
String redirectUrl = request.getContextPath() + url;
redirectUrl = response.encodeRedirectURL(redirectUrl);
if (logger.isDebugEnabled()) {
logger.debug("Redirecting to '" + redirectUrl + "'");
}
response.sendRedirect(redirectUrl);
}