Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在spring过滤器中设置视图名称_Java_Spring_Jsp_Tiles_Servlet Filters - Fatal编程技术网

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
,它扩展了spring
GenericFilterBean
。如果发生错误,我想显示一个用瓷砖装饰的错误页面

有没有办法从过滤器中设置视图名称?


错误过滤器
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重定向,但给出相同的“没有这样的页面错误”内容)

必须有一种方法可以用SpringMVC实现,但我认为重定向就足够了

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用于说明重定向和转发之间的区别。