实施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的类,而我的FrameworkEndpointHandlerMapping被丢弃,从而导致应用程序中的错误。

我已经搜索了其他类似问题,但其中大多数回答isAssignableFrom方法使用不正确(类和函数参数的混合使用)。因为JUnit在工作,所以这里不是这种情况。

怀疑是导入的jar文件是问题,我将其限制为以下文件:


spring-beans-4.1.4.RELEASE.jar
春季安全oauth2-2.0.6.RELEASE.jar
spring-webmvc-4.1.4.RELEASE.jar(也尝试使用4.0.9)
弹簧核心-4.1.4.RELEASE.jar
...


您有任何解决方案的想法吗?

有关更多信息,请参见以下资源:

我自己的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));
    }
}


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>


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>


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

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

感谢您阅读此问题,

劳伦特

最佳答案

这真的很奇怪。面对这样的问题,我首先怀疑在子应用程序上下文中找不到该bean,或者该bean被同名的bean隐藏。但是正如您说的那样,您设法看到ClassUtils.isAssignableFrom被调用并返回了False,我承认找到并测试了正确的bean。

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

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

关于java - 服务器启动过程中,函数isAssignableFrom返回false,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30195166/

10-11 22:29
查看更多