服务器启动过程中,函数isAssignableFrom返回false
实施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
并且将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 (also tried with the 4.0.9)
- spring-core-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。但是正如您说的那样,您设法看到该对象ClassUtils.isAssignableFrom
已被调用并返回了False
,我承认找到并测试了正确的bean。
我可以想象的最后一个问题是classpath中有多个HandlerMapping实例。正如JonSkeet的评论所建议的那样,如果spring-
webmvc.jar类路径中有多个,则用于的类加载器FrameworkEndpointHandlerMapping
可以选择一个,而用于自定义的类加载器DispatcherServlet
可以选择另一个。
如果使用的是maven,请控制依赖图。而且,无论如何,请控制您应用和servlet容器的lib文件夹中的jar列表,以及可以通过全局CLASSPATH环境变量公开访问的jar列表
以上是 服务器启动过程中,函数isAssignableFrom返回false 的全部内容, 来源链接: utcz.com/qa/409121.html