Java 在spring过滤器中设置视图名称
我有一个Java 在spring过滤器中设置视图名称,java,spring,jsp,tiles,servlet-filters,Java,Spring,Jsp,Tiles,Servlet Filters,我有一个ErrorFilter,它扩展了springGenericFilterBean。如果发生错误,我想显示一个用瓷砖装饰的错误页面 有没有办法从过滤器中设置视图名称? 错误过滤器 com.abc.filter.ErrorFilter 错误页面 /jsp/errorpage.jsp 这是web.xml中的配置,errorfilter中的doFilter方法如下: public void doFilter(ServletRequest req, ServletResponse resp,
ErrorFilter
,它扩展了springGenericFilterBean
。如果发生错误,我想显示一个用瓷砖装饰的错误页面
有没有办法从过滤器中设置视图名称?
错误过滤器
com.abc.filter.ErrorFilter
错误页面
/jsp/errorpage.jsp
这是web.xml
中的配置,errorfilter
中的doFilter
方法如下:
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);
}
}
当前errorpage没有用平铺装饰,因此我想用普通的页眉和页脚装饰它,并从过滤器中调用该视图名称
可能吗
编辑:
基本上,我们希望能够执行类似于控制器方法的操作,即返回“视图名称”
已尝试:
- httpResponse.sendRedirect(“errorPageView”);不起作用,它重定向到
- request.getRequestDispatcher(“errorPageView”).forward(请求,响应);也没有,与上面类似(没有http重定向,但给出相同的“没有这样的页面错误”内容)
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"));
}
}
注意,不要犯错误 我认为这是不可能的,因为这是一个servlet过滤器,它将在应用spring请求映射器servlet之后应用。因此,基本上,请求映射器servlet认为它已经完成,并将请求传递回servlet容器 视图名称只在spring内部工作——在spring之外的servlet容器中,您必须讨论URL,而不是视图名称 重定向到特定url将起作用。为此,您必须了解重定向和转发之间的区别 重定向会将以下标头发送到客户端: 地点: 以及状态代码301(永久重定向,让客户端知道它可以缓存此信息)或307(临时重定向,告诉客户端下次应该再次询问,因为重定向可能会更改) 请求调度器上的转发基本上模拟了一个新的请求,您可以将请求发送到同一容器中的任何servlet。这意味着,您还必须考虑上下文路径,这意味着@iimuhin给出的答案:
response.sendRedirect(
request.getContextPath() +
getFilterConfig().getInitParameter("errorPage"));
这实际上是正确的选择。您可以(应该)添加日志以查看实际发生的情况以及实际使用的路径
此外,您必须了解缓冲。servlet响应通常是缓冲的,在缓冲区已满或整个处理完成之前,不会向客户端发送任何内容
刷新时,首先写入头。这意味着在刷新响应后更改标头是不可能的,因为它们已经发送出去了
这就是为什么servlet可以强制刷新,但通常不应该
在您的情况下,您可能希望增加响应上的缓冲区大小:
response.setBufferSize(int size)
在调用chain.doFilter()以避免过早刷新之前。为什么不使用spring的错误处理机制?这是一篇关于它的好文章(有例子)——
除此之外,我不确定是否有一种干净的方法可以做到这一点。其他建议可能是调用应用程序以获取错误页面响应,并用该响应替换响应输出(在这种情况下,您还需要使用“缓冲”http响应以确保流尚未刷新),或者重定向到错误url。过滤器在Spring之前出现。SpringBean可以使用ApplicationContextAware机制注入过滤器,但形成SpringMVC视图意味着您必须在过滤器中掌握整个SpringMVC框架。我认为这是不可能的,您必须使用RequestDispatcher将请求转发到您自己的自定义视图,而不是spring视图。只需检查重定向url即可。您可以使用url访问页面
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);
}
sendRedirect只会将客户端浏览器重定向到指定的URL,绕过任何视图名称解析。如果发问者希望显示来自控制器的错误页面,则您的建议有效。他想要的是在请求传递给控制器之前,从Servlet过滤器中构造一个错误页面。因此,异常处理在这里无法工作。不过,您的第二个建议值得注意。感谢您的回复和评估,但为什么您认为servlet筛选器无法捕获spring控制器中或spring控制器执行后抛出的异常(换句话说,在控制器执行后返回的过程中)?我回答的要点是:-如果可以,请使用sring功能-如果您(出于任何原因)无法使用它,重定向或响应解析(在筛选器中)仍然是一个选项。但只有在尚未做出回应的情况下,这才可能奏效。有道理吗?我完全按照你说的做了。在自定义身份验证筛选器中,我检查了身份验证,如果出现任何异常,我将请求转发给控制器,并向请求对象添加错误属性。在转发时,我检查了响应是否已经提交。我还增加了缓冲区限制,以避免意外刷新。在控制器中,我从请求对象获取添加的属性,并从那里返回错误页面视图。你能指导我从过滤器中创建错误页面视图吗?我能处理过滤器中的异常吗?非常感谢您对此事的详细解释+1用于说明重定向和转发之间的区别。