1

我的问题: 我不确定,但我相信有一个 SAP 提供的身份验证 Servlet 过滤器,重定向到 SAP 默认登录页面(这当然会导致问题,因为它没有返回 xml 响应),这是不FullAjaxExceptionHandler被调用。我正在寻求帮助来确定真正的根本原因,或者是否有任何替代方法来解决它。

我的环境:

  • SAP Netweaver 7.4(支持 JSF 2.1.x 的 servlet 2.5)
  • SAP JVM 6.1(SAP 的 1.6 jvm)
  • 莫哈拉 2.1.29
  • 全方位 1.11

背景:

我有一个session-config session-timeout设置为 1 分钟的示例应用程序,并FullAjaxExceptionHandlerFactoryfaces-config.xml.

web.xml

...

<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/errorPage.xhtml</location>
</error-page>
<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/WEB-INF/viewExpired.xhtml</location>
</error-page>
<session-config>
    <session-timeout>1</session-timeout>
</session-config>
... 

面孔-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd" version="2.1">

<factory>
    <exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
...

我确定 Netweaver 的工作方式是在一分钟后将会话标记为“过期”,但会话本身不会立即清理(我知道这在 Web 容器中很常见)。如果我在会话过期后但在会话被服务器完全删除之前提交 ajax 请求,则会FullAjaxExceptionHandler启动并正确显示我的查看过期页面。但是,如果服务器已经清理了过期的会话,则什么也不会发生,并且页面会显示为“死”,直到执行物理刷新。

通过阅读@balusc 的许多答案,我怀疑 SAP 提供的 http 过滤器正在启动,它将 ajax 请求重定向到 SAP 登录页面,这就是应用程序无法正常工作的原因。

有什么方法可以确定是什么原因造成的?如果它是服务器提供的过滤器,是否有覆盖它?

4

1 回答 1

1

再次感谢 BalusC!你把我推向了正确的方向。

SAP Netweaver 有一个global-web.xml文件,它定义了一些默认功能。其中之一如下:

<filter>
    <filter-name>AuthenticationFilter</filter-name>
    <filter-class>com.sap.engine.services.servlets_jsp.server.servlet.AuthenticationFilter</filter-class>
</filter>

所以我所做的就是<filter-name>在我自己的 web.xml 中使用相同的,提供一个扩展 SAP 的身份验证过滤器的类。

<filter>
    <filter-name>AuthenticationFilter</filter-name>
    <filter-class>com.example.AjaxAwareAuthenticationFilter</filter-class>
</filter>

由于<filter-name>相同,因此在我本地定义的web.xml获胜。

这是我的课:

package com.example;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.sap.engine.services.servlets_jsp.server.servlet.AuthenticationFilter;

public class AjaxAwareAuthenticationFilter extends AuthenticationFilter {
    @Override
    public void destroy() {
        super.destroy();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;

        HttpSession session = httpRequest.getSession(false);
        if (session == null && "partial/ajax".equals(httpRequest.getHeader("Faces-Request"))) {
                // JSF ajax request. Return special XML response which instructs
                // JavaScript that it should in turn perform a redirect.
                response.setContentType("text/xml");
                response.getWriter()
                    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
                    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>",
                            httpRequest.getContextPath());
        } else {
            super.doFilter(request, response, chain);
        }
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        super.init(config);
    }
}
于 2015-09-16T13:37:58.073 回答