当前位置: 首页 > 知识库问答 >
问题:

如何依次调用Servlet和过滤器

谷永贞
2023-03-14

大家好,我正在开发一个web应用程序,在调用web中提到的Servelet时遇到了问题。xml。

这是我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

     <servlet>
            <servlet-name>FileServlet</servlet-name>
            <servlet-class>com.tpg.fileserver.FileServlet</servlet-class>
     </servlet>
    <servlet-mapping>
            <servlet-name>FileServlet</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    <filter>
            <filter-name>AuthorizationFilter</filter-name>
            <filter-class>com.tpg.fileserver.AuthorizationFilter</filter-class>
      </filter>
      <filter-mapping>
            <filter-name>AuthorizationFilter</filter-name>
            <url-pattern>/*</url-pattern>
      </filter-mapping>

  </web-app>

问题是,当我试图运行我的应用程序时,我希望先运行身份验证过滤器,然后再运行文件Servelet。现在发生的事情与我想要的正好相反。我也尝试过使用0作为文件Servelet,但没有帮助。下面提到的是我的过滤器类代码。

public class AuthorizationFilter implements Filter  {

    private static final String kNotAuthorizedUrl = "/NotAuthorized.html";
    private static final String kTrustedHostsFileName = "trusted_hosts.txt";
    private static final String kPublicFilesFileName = "public_files.txt";

    private static final String TRUSTED_HOSTS = "TRUSTED_HOSTS";
    private static final String PUBLIC_FILES = "PUBLIC_FILES";
    private static Properties itsProperties = null;
    public static final String kPropertySingleSignOnURL = "sso-url";
    private static final String kPropertiesFileName = "metadata.properties";
    private static boolean itsInitialized = false;

    private static synchronized void initialize() {
        if (!itsInitialized) {
            try {
                ProductMetadataAPI.setProduct(Version.kProductName, Version.kPhysical);
                System.out.println("Inside Initialize");
                PersistenceAPI.isDebugging = true;
                JNDIConnectionFactory connFactory = new JNDIConnectionFactory("DataSource"); // IDB

                SingleSignOnAuthenticator.setAuthenticationUrl(ConfigurationUtils.getProperties().getProperty(kPropertySingleSignOnURL));

                SecurityAPI.setSecurity(
                    SecurityAPI.makeSecurity(
                        new StandardFactory(),
                        new PersistenceRepository(connFactory),
                        new CommonsBase64Codec(),
                        new SingleSignOnAuthenticator()));

                itsInitialized = true;
            } catch (Throwable e) {
                LoggerClass.logErr(e);
            }
        }
    }

    private void requestAuthentication(HttpServletResponse response) {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.addHeader("WWW-Authenticate", "BASIC Realm=\"Single Sign-on\"");
        LoggerClass.logInfoMsg("SSO not set. redirecting to siteminder......");
    }


    public void doFilter(ServletRequest inRequest, ServletResponse inResponse, FilterChain chain) throws IOException, ServletException {
        try {
            HttpServletRequest request = (HttpServletRequest) inRequest;
            HttpServletResponse response = (HttpServletResponse) inResponse;
            System.out.println("Before Setting Serervlet Context");
            ConfigurationUtils.setCurrentServletContext(request.getSession().getServletContext());
            System.out.println("After Setting Serervlet Context");
            initialize();

            if (request instanceof HttpServletRequest && (request.getMethod().equals("GET") || request.getMethod().equals("POST"))) {
                String remoteHost = "", authorization = "", userName = "", password = "";
                HttpServletRequest r = (HttpServletRequest)request;
                Enumeration<String> e = r.getHeaderNames();
                while (e.hasMoreElements()) {
                    String headerName = e.nextElement();
                    LoggerClass.logInfoMsg(headerName + "=" + r.getHeader(headerName));
                }
                LoggerClass.logDebugMsg("Proxy-Client-IP is :" + r.getHeader("Proxy-Client-IP"));
                LoggerClass.logDebugMsg("Remote-Address-IP is :" + r.getRemoteAddr());


                remoteHost = r.getHeader("Proxy-Client-IP");
                if (remoteHost == null) {
                    remoteHost = r.getRemoteAddr();
                    LoggerClass.logDebugMsg("Remote-Address-IP ["+remoteHost + "] is requesting " + r.getRequestURI());
                }else{
                    LoggerClass.logDebugMsg("Proxy-Client-IP ["+remoteHost + "] is requesting " + r.getRequestURI());
                }

                authorization = r.getHeader("Authorization");
                if (authorization != null) {
                    final int index = authorization.indexOf(' ');
                    if (index > 0) {
                        final String[] credentials = StringUtils.split(new String(Base64.decodeBase64(authorization.substring(index))), ':');

                        if (credentials.length == 2) {
                            userName = credentials[0].toUpperCase();
                            password = credentials[1];
                        }
                    }
                }

                if (isSiteminderAuthenticationPresent(r)) {
                    LoggerClass.logInfoMsg("Inside Siteminder Logic ......");
                    chain.doFilter(request, response);
                    return;
                } else if (isPublic(request) || isTrusted(remoteHost)) {
                    LoggerClass.logInfoMsg("Inside Public/Trusted Host Logic ......");
                    chain.doFilter(request, response);
                    return;
                } else if (!isBasicAuthenticationPresent(userName, password)) {
                    LoggerClass.logInfoMsg("Failed in Basic Authentication Present.....");
                    requestAuthentication(response);
                } else if (!isBasicAuthenticationValid(r.getSession(), userName, password)) {
                    LoggerClass.logInfoMsg("Failed in Basic Authentication Validation.....");
                    requestAuthentication(response);
                } else {
                    chain.doFilter(request, response);
                }
            }
            response.sendRedirect(request.getContextPath() + kNotAuthorizedUrl);
        } catch (Exception e) {
            LoggerClass.logErr(e);
            throw new RuntimeException(e);
        }
    }
}

下面是我的Servlet部分代码:

public class FileServlet extends HttpServlet
{
public FileServlet()
    {
         System.out.println("In fileServlet");
         this.itsRootDir = Common.getRequiredProperty(Common.kPropertyRootDir);
            // some business logic
    }
@Override public void doGet(HttpServletRequest inRequest, HttpServletResponse inResponse)
    throws ServletException, IOException
    {
        String theRelFileName = Common.extractFileName(inRequest, false);
        String theFileName = this.itsRootDir + theRelFileName;
        File theFile = new File(theFileName);
     //Some more Business Logic
}
}           

下面是我在应用程序日志中获得的Sysout日志。我注意到一件奇怪的事。首先调用文件Servlet,然后是授权过滤器,然后再次调用文件Servlet。

[8/8/14 0:54:05:109 EDT] 0000002b SystemOut     O In fileServlet
[8/8/14 0:54:05:161 EDT] 0000002b SystemOut     O In Authoriazation Filter
[8/8/14 0:54:05:232 EDT] 0000002b SystemOut     O In fileServlet

共有2个答案

葛季萌
2023-03-14

上述问题的答案是,FileServlet中的构造函数是在执行过滤器之前调用的。为了解决这个问题,我将构造函数更改为一个公共方法,该方法在Servlet的doget()方法中被调用。更改后,首先调用过滤器,然后调用servlet。

海保臣
2023-03-14

过滤器总是在webapp启动期间按照web中定义的顺序初始化。xml

默认情况下,servlet仅在其url模式的第一个HTTP请求期间初始化。

所以在本例中,首先是webapp的web。xml将被解析,每个过滤器都将在网站中找到。xml将被创建一次,并保存在服务器的内存中

现在,当一个请求来自像/*这样的url模式时,容器会查找该模式,并找到servlet的映射,因此初始化servlet。然后调用过滤器来处理请求。

要解决这个问题,可以更改servlet的url模式。当用户输入一些url模式(如/*重定向到filter类)时,如果他成功地进行了身份验证,则重定向到使用其他url模式指定的servlet,或者重定向到错误页面

 类似资料:
  • 我正在研究一个合作医疗系统。 我的代码在url调用的servlet的

  • 我使用Atmosphere 1.0.15在Tomcat下处理推送通知,几年来一直运行良好。最近,我在Tomcat中添加了一个简单的过滤器作为测试,它(目前)只记录传入的URL并继续。问题在于,Tomcat似乎根本不会对my Atmosphere处理的任何servlet路径调用过滤器,但对任何其他servlet路径调用过滤器都很好。 以下是我网站的相关部分。xml: 这就是我的氛围。xml: 奇怪的

  • 我正在使用Servlet过滤器来实施访问控制。扩展it以测试用户角色的最佳方式是什么?我能想出几种解决方案,但没有一种是优雅的。 编写角色测试并不难。但是如何将角色传递给给定url的过滤器? e、 在网络上。xml 谢谢

  • 问题内容: 我正在尝试找到一种方法,可将请求从过滤器重定向到登录页面,但我不知道如何从servlet重定向。我搜索了,但发现的是方法。我在过滤器的响应对象上找不到此方法。是什么原因 我该如何解决? 问题答案: 在Filter中,响应是而不是。因此将强制转换为。 如果使用上下文路径: 也不要忘记在最后打电话。

  • 问题内容: Servlet和Filter有什么区别?您建议使用什么来授权页面? 问题答案: 当你要根据特定条件过滤和/或修改请求时,请使用。使用时要控制,预处理和/或后处理请求。 在Java EE的教程中提到有关筛选如下: 筛选器是可以转换请求或响应的标头和内容(或两者)的对象。过滤器与Web组件的不同之处在于,过滤器本身通常不会创建响应。相反,过滤器提供的功能可以“附加”到任何类型的Web资源。

  • Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。 可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet。Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。 Servlet 过滤器是可用于 Servlet