设置春季会话,并通过XML重新使用现有的弹簧安全性



我继承了使用弹簧组件的现有Web应用程序,包括Spring Security。

我需要添加使应用程序不播放的功能,以供云中托管,因此我正在尝试启用此应用程序的春季会话。但是,作为一个相对的春天新人,我很难做到这一点。

没有问题设置弹簧数据,将redis作为春季会议的前体工作,但是在春季会话文档上https://docs.spring.io/spring-session/docs/docs/current/current/referent/referent/referent/html5/#httpsession-xml-spring-configuration使我走上了连续的例外路径或内部服务器错误。

我正在发布pom.xml的所有/相关部分,applicationContext.xml,servlet-context.xml和web.xml文件,希望有人能告诉我我做错了什么,需要以不同的方式配置,或我缺少的东西,仍然需要添加。

我看到的错误是:

SEVERE [http-nio-8093-exec-42] org.apache.catalina.core.ApplicationContext.log StandardWrapper.Throwable
 java.lang.NoClassDefFoundError: com/lambdaworks/redis/RedisException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.getDeclaredMethods(Class.java:1975)
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:609)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:521)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:507)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:241)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1069)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1042)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:633)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:681)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:552)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1183)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1099)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:779)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:133)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: com.lambdaworks.redis.RedisException
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1285)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1119)
    ... 45 more

我在网上找到了一个建议,即我应该在我的pom.xml中包括生菜的依赖性来解决此问题:

<dependency>
  <groupId>biz.paluch.redis</groupId>
  <artifactId>lettuce</artifactId>
  <version>4.4.0.Final</version>
</dependency>

,但包括该依赖性产生了不同的例外,该例外说我现在有多个重复的实例:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.data.redis.connection.RedisConnectionFactory] is defined: expected single matching bean but found 2: org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory#0,redisConnectionFactory)

如果有人可以帮助我弄清楚我做错了什么,我将非常感激!

pom.xml (相关部分)

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <httpcomponents-client.version>4.3.3</httpcomponents-client.version>
    <httpcomponents-core.version>4.3.3</httpcomponents-core.version>
    <spring.framework.version>4.2.5.RELEASE</spring.framework.version>
    <spring.security.version>4.1.0.RELEASE</spring.security.version>
</properties>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
<dependencies>
    <!-- SPRING SECURITY -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${spring.security.version}</version>
    </dependency> 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring.security.version}</version>
    </dependency> 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <!-- SPRING -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.framework.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <!-- SPRING DATA -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>1.10.1.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <artifactId>spring-context</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- SPRING DATA WITH REDIS -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.8.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    <!--  SPRING SESSION  -->
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
        <version>1.3.1.RELEASE</version>
        <type>pom</type>
    </dependency>
  </dependencies>
</project>

ApplicationContext.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:property-placeholder location="classpath:app.properties" />
    <bean id="usingAuthentication" class="java.lang.Boolean">
        <description>Flag indicating if authentication is being used.</description>
        <constructor-arg>
            <value>${usingAuthentication}</value>
        </constructor-arg>
    </bean>
    <bean id="jaasmineAppName" class="java.lang.String">
        <description>The name of the JAAS configuration to use when sending requests to the web api.</description>
        <constructor-arg>
            <value>jaasmine.login</value>
        </constructor-arg>
    </bean>
    <bean id="authenticationService" class="com.logiclander.jaasmine.authentication.KeyTabAuthenticationService">
        <description>Obtains kerberos tickets when the kerberosClientPrincipal sends requests to the web api.</description>
        <constructor-arg ref="jaasmineAppName"/>
    </bean>
    <!-- HTTP CLIENT -->
    <bean id="poolingConnectionManager"
        class="jaxrs.ext.http4client.CustomClientConnectionManager">
        <property name="maxTotalConnection" value="200" />
        <property name="maxTotalPerRoute" value="20" />
    </bean>
    <bean id="restHttpClient"
        class="jaxrs.ext.http4client.CustomHttpClient"
        scope="prototype">
        <constructor-arg name="connManager" ref="poolingConnectionManager" />
        <property name="sslv3" value="false"/>
    </bean>
    <bean id="clientExecutor" class="org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor">
        <constructor-arg name="httpClient" ref="restHttpClient"/>
    </bean>
    <!-- HTTP CLIENT FOR NVPAPI -->
    <bean id="nvpUserPwdCredential"
        class="org.apache.http.auth.UsernamePasswordCredentials">
        <constructor-arg name="userName"> <value>xyzf</value> </constructor-arg>
        <constructor-arg name="password"> <value>xxxx</value> </constructor-arg>
    </bean>
    <bean id="nvpPoolingConnectionManager"
           class="jaxrs.ext.http4client.CustomClientConnectionManager">
        <property name="maxTotalConnection" value="200" />
        <property name="maxTotalPerRoute" value="20" />
    </bean>
    <bean id="nvpRestHttpClient"
        class="jaxrs.ext.http4client.CustomHttpClient"
        scope="prototype">
        <constructor-arg name="connManager" ref="nvpPoolingConnectionManager" />
        <property name="credentials" ref="nvpUserPwdCredential"/>
        <property name="sslv3" value="false"/>
    </bean>
    <bean id="nvpClientExecutor"
        class="org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor">
        <constructor-arg name="httpClient" ref="nvpRestHttpClient"/>
    </bean>
    <!--
    |
    |  REDIS
    |
    -->
    <bean id="stringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    <bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="localhost" p:port="6379" />
    <!-- redis template definition -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="redisConnectionFactory">
        <property name="keySerializer" ref="stringSerializer"/>
        <property name="valueSerializer" ref="stringSerializer"/>
    </bean>
    <!--
    |
    |  SPRING SECURITY
    |
    -->
    <bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
    <security:http auto-config="false" entry-point-ref="http403EntryPoint" use-expressions="true" disable-url-rewriting="true">
        <security:intercept-url pattern="/logout/**" access="permitAll" requires-channel="${securityChannel}" />
        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="${securityChannel}"/>
        <security:intercept-url pattern="/user/**" access="hasAnyRole('ROLE_STUDENT','ROLE_STAFF')" requires-channel="${securityChannel}"/>
        <security:intercept-url pattern="/**" access="permitAll" requires-channel="${securityChannel}"/>
        <security:custom-filter position="PRE_AUTH_FILTER" ref="${cPreAuthFilter}" />
        <security:custom-filter position="LOGOUT_FILTER" ref="logoutFilter" /> 
        <security:csrf disabled="true" />
    </security:http>
    <bean id="workstationFilter"
          class="webmvc.security.WorkstationPreAuthFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
    </bean>
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="preauthAuthProvider"/>
    </security:authentication-manager>
    <bean id="preauthAuthProvider"
          class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService">
            <bean id="userDetailsServiceWrapper"
                  class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <property name="userDetailsService" ref="${appUserDetailsService}"/>
            </bean>
        </property>
    </bean>
    <bean id="mockUserDetailsService" 
        class="webmvc.security.MockAdUserDetailsService">
    </bean>
    <bean id="adUserDetailsService"
        class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
        <constructor-arg ref="ldapSearch"/>
        <constructor-arg ref="ldapAuthoritiesPopulator"/>
        <property name="userDetailsMapper" ref="activeDirectoryUserDetailsContextMapper"/>
    </bean>
    <bean id="ldapSearch"
                class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
        <constructor-arg value="OU=People,dc=ad,dc=uil,dc=edu"/> <!-- use-search-base -->
        <constructor-arg value="(sAMAccountName={0})"/> <!-- user-search-filter -->
        <constructor-arg ref="ldapServer"/>
    </bean>
    <bean id="ldapAuthoritiesPopulator"
                class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
        <constructor-arg ref="ldapServer"/>
        <constructor-arg value="ou=ci,ou=georgia,ou=Services,ou=SERVICES,ou=City,dc=ad,dc=uil,dc=edu"/> <!-- group search base -->
        <property name="groupRoleAttribute" value="cn"/> <!-- cn is default -->
        <property name="rolePrefix" value="" /> <!-- default is ROLE_ -->
        <property name="convertToUpperCase" value="false"/>
        <property name="searchSubtree" value="true"/> <!-- deep search -->
        <property name="groupSearchFilter" value="(member:1.2.840.113556.1.4.1941:={0})"/> <!-- MAGIC -->
    </bean>
    <bean id="ldapServer"
                class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="ldaps://ad.business.com:636"/>
        <property name="userDn" value="cn=c-webmvc,ou=service-accounts,ou=georgia,ou=CI-Services,ou=CI,ou=City,dc=ad,dc=uil,dc=edu"/>
        <property name="password" value="xxxx"/>
    </bean>
    <bean id="activeDirectoryUserDetailsContextMapper"
            class="webmvc.security.ActiveDirectoryUserDetailsContextMapper">
    </bean>
    <!--
    |
    |    LOGOUT CONFIGS
    |
    -->
    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg index="0" value="${cLogoutUri}" />
        <constructor-arg index="1">
            <list>
                <ref bean="securityContextLogoutHandler" />
                <ref bean="cookieClearingLogoutHandler" />
            </list>
        </constructor-arg>
        <property name="filterProcessesUrl" value="/logout" />
    </bean>
    <bean id="securityContextLogoutHandler" 
                class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
        <property name="invalidateHttpSession" value="true"/>
    </bean>
    <bean id="cookieClearingLogoutHandler" class="org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler">
        <constructor-arg>
            <!-- Names of the cookies you want to remove when user logs out -->
            <list>
                <value>JSESSIONID</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

Servlet-context.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
   xmlns:util="http://www.springframework.org/schema/util"
   xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    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/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<context:component-scan base-package="edu.illinois.cis.webmvc" />
<!-- expose property file to controllers -->
<util:properties id="defaultProps" location="classpath:default.properties"/>
<util:properties id="appProps" location="classpath:app.properties"/>        
<mvc:annotation-driven />
<mvc:resources mapping="/static/**" location="/static/" cache-period="3600"/>
<bean id="viewProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:default.properties</value>
            <value>classpath:gened.properties</value>
            <value>classpath:app.properties</value>
        </list>
    </property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
    <property name="exposedContextBeanNames">
        <list>
            <value>viewProps</value>
        </list>
    </property>
</bean>
<bean id="messageSource"
                  class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="classpath:messages" />
    <property name="defaultEncoding" value="UTF-8" />
    <property name="cacheSeconds" value="5" />
</bean>
<!-- Use the combination of <context:annotation-config/> (above) and RedisHttpSessionConfiguration because 
     Spring Session does not yet provide XML Namespace support (see gh-104). This creates a Spring Bean with 
     the name of springSessionRepositoryFilter that implements Filter. The filter is what is in charge of replacing the HttpSession implementation to be backed by Spring Session. In this instance Spring Session is backed by Redis.  -->
  <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
  <!-- Create a RedisConnectionFactory that connects Spring Session to the Redis Server. 
     Configure the connection to connect to localhost on the default port (6379) -->
  <bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
</beans>

web.xml

<web-app version="3.0" 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-app_3_0.xsd">
<servlet>
  <servlet-name>courses</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
  </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>courses</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<!-- load applicationContext.xml -->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
<!-- ensure that the Servlet Container (i.e. Tomcat) uses the springSessionRepositoryFilter for every request -->
<!-- DelegatingFilterProxy will look up a Bean by the name of springSessionRepositoryFilter and cast it to a Filter -->
<!-- For every request that DelegatingFilterProxy is invoked, the springSessionRepositoryFilter will be invoked -->
<filter>
  <filter-name>springSessionRepositoryFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>springSessionRepositoryFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- Spring Security -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
  <error-code>404</error-code>
  <location>/error/404</location>
</error-page>
<error-page>
  <error-code>403</error-code>
  <location>/error/403</location>
</error-page>

org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type 
[org.springframework.data.redis.connection.RedisConnectionFactory] is 
defined: expected single matching bean but found 2: 
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory#0
,redisConnectionFactory)

例外意味着春季正在等待RedisConnectionFactory型豆类,但没有办法定义哪种豆是要使用的豆子,然后我认为它正在发生,因为在applicationContext.xml上,有一个bean清除为

<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="localhost" p:port="6379" />

,但在servlet-context.xml中也声明了一个bean为:

<bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>

根据JedisConnectionFactoryLettuceConnectionFactory的Javadoc,它们都实现了RedisConnectionFactory接口。

我的结论是RedisHttpSessionConfiguration期望RedisConnectionFactory型豆类,但由于有两个RedisConnectionFactory bean,因此无法注入。基于此,您可以尝试从servlet-context.xml中删除LettuceConnectionFactory BEAN,因为redisConnectionFactory BEAN是类型RedisConnectionFactory,并且已经从applicationContext.xml创建。

我希望此信息可以帮助您解决此问题。

最新更新