函数 isAssignableFrom 在服务器启动期间返回 false

2024-05-05

实施oauth2系统,我在使用以下代码时遇到一些问题:

import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.servlet.HandlerMapping;

...
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);

确实,作为班级FrameworkEndpointHandlerMapping正在实现接口HandlerMapping,这个函数应该总是返回true。当我对此函数运行单元测试时就是这种情况。但是,在服务器启动期间,该函数返回false(使用调试器检查)。这是一个很大的问题,因为当DispatcherServlet被实例化后,它会搜索实现的类HandlerMapping and my FrameworkEndpointHandlerMapping被丢弃会导致应用程序中出现错误。

我搜索过类似这个问题的其他问题,但大多数人的回答是isAssignableFrom方法未正确使用(类和函数参数的混合)。这里的情况并非如此,因为 JUnit 正在工作。

怀疑是进口的jar文件是问题所在,我将它们限制为以下文件:

  • spring-beans-4.1.4.RELEASE.jar
  • spring-security-oauth2-2.0.6.RELEASE.jar
  • spring-webmvc-4.1.4.RELEASE.jar(也尝试过4.0.9)
  • spring-core-4.1.4.RELEASE.jar
  • ...

您有什么解决方案可以探索吗?

欲了解更多信息,请参阅以下来源:

My own DispatcherServlet(构造函数与String作为参数由 JUnit 测试调用,并在系统启动期间调用默认构造函数)

import org.junit.Assert;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

public class MobileDispatcherServlet extends DispatcherServlet
{

    private static final long serialVersionUID = 1L;

    public MobileDispatcherServlet()
    {
        super();
        HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
    }

    public MobileDispatcherServlet(final WebApplicationContext webApplicationContext)
    {
        super(webApplicationContext);
        final FrameworkEndpointHandlerMapping handlerMapping = webApplicationContext.getBean(FrameworkEndpointHandlerMapping.class);

        HandlerMapping.class.isAssignableFrom(handlerMapping.getClass());
    }

    public MobileDispatcherServlet(final String test)
    {
        Assert.assertTrue(HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class));
    }
}

The oauth配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
                        http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

    <!-- Root of the configuration -->
    <!-- The FrameworkEndpointHandlerMapping is created here -->
    <oauth:authorization-server client-details-service-ref="clientDetails"
                                token-services-ref="tokenServices"
                                user-approval-handler-ref="userApprovalHandler"
                                authorization-endpoint-url="/oauth/authorize.action"
                                token-endpoint-url="/oauth/token.action" >
        <oauth:authorization-code authorization-code-services-ref="authorizationCodeServices" disabled="false" />
        <oauth:refresh-token />
    </oauth:authorization-server>

    ...

</beans>

The web.xml:

<web-app id="sitestorefront" version="3.0" 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.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app.xsd" 
         metadata-complete="true">

...

    <context-param>
        <description>
            The 'contextConfigLocation' param specifies where your configuration files are located.
            The 'WEB-INF/config/web-application-config.xml' file includes several other XML config
            files to build up the configuration for the application.
        </description>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/config/web-application-config.xml</param-value>
    </context-param>
    <context-param>
        <param-name>tagpoolMaxSize</param-name>
        <param-value>50</param-value>
    </context-param>

<servlet>
        <description>
            DispatcherServlet
        </description>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>be.sbh.site.storefront.oauth2.MobileDispatcherServlet</servlet-class>
        <init-param>
            <description>
                Specifies the location for Spring MVC to load an additional XML configuration file.
                Because hybris is already configured with the XML spring configuration files to load
                we must set this param value to EMPTY in order to prevent loading of the default
                /WEB-INF/applicationContext.xml file.
            </description>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!-- Map all requests to the DispatcherServlet -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

...

</web-app>

The web-application-config.xml导入所有配置文件(其中,oauth配置文件)。其中一个有一个<mvc:annotation-driven />启用 mvc 注释。

我试图将我的资源限制在与我相关的资源上。如果您需要更多,请随时询问我。

感谢您阅读这个问题,

Laurent


这实在是太奇怪了。面对这样的问题,我首先怀疑该bean没有找到,或者被子应用程序上下文中的同名bean隐藏。但正如你所说,你设法看到了这一点ClassUtils.isAssignableFrom被呼叫并返回False,我承认找到并测试了正确的bean。

我能想到的最后一个问题是类路径中 HandlerMapping 的多个实例。正如 JonSkeet 的评论所建议的,如果您有多个spring-webmvc.jar在类路径中,类加载器FrameworkEndpointHandlerMapping可以选择一个,以及您自定义的类加载器DispatcherServlet可以选择另一个。

如果您使用 Maven,请控制依赖关系图。无论如何,请控制应用程序和 servlet 容器的 lib 文件夹中的 jar 列表,以及可通过全局 CLASSPATH 环境变量公开访问的 jar 列表

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数 isAssignableFrom 在服务器启动期间返回 false 的相关文章

随机推荐