2017-08-31 4 views
0

J'ai hérité d'une application Web existante qui utilise les composants Spring, y compris Spring Security.Configuration de Spring Session et Redis via XML avec Spring Security existant

Je dois ajouter la possibilité d'avoir une application sans session, pour l'hébergement dans le cloud, et j'essaie donc d'activer Spring Session pour cette application. En tant que nouveau venu au printemps, cependant, j'ai de la difficulté à le faire. Il n'y a pas eu de problèmes lors de la configuration de Spring Data avec Redis en tant que précurseur de Spring Session, mais la suite de la documentation de Spring Session au https://docs.spring.io/spring-session/docs/current/reference/html5/#httpsession-xml-spring-configuration m'a amené un chemin d'exceptions successives ou d'erreurs internes du serveur.

Je publie toutes les parties pertinentes des fichiers pom.xml, applicationContext.xml, servlet-context.xml et web.xml dans l'espoir que quelqu'un puisse me dire ce que je fais de mal, doit configurer différemment , ou ce qui me manque et encore besoin d'ajouter.

L'erreur que je vois est:

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 

J'ai trouvé une suggestion en ligne que je devrais inclure une dépendance pour la laitue dans mon pom.xml pour résoudre ce:

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

mais y compris cette dépendance génère une exception différente, qui indique que j'ai maintenant plusieurs instances de RedisConnectionFactory:

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) 

Je serais très reconnaissant si quelqu'un pouvait m'aider à comprendre ce que je fais mal!

pom.xml (sections pertinentes)

<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> 

+0

Merci, Daniel. Votre solution a fonctionné pour moi - j'avais juste besoin de supprimer le bean supplémentaire qui créait une double instance de l'interface RedisConnectionFactory. – rls

Répondre

1
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) 

L'exception signifie que le ressort est en attente pour un bean de type RedisConnectionFactory mais il n'y a aucun moyen de définir laquelle est la fève à utiliser, puis I pense que cela se produit parce qu'à applicationContext.xml il y a un haricot apurés comme

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

mais aussi dans servlet-context.xml il y a un haricot déclaré que:

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

Et selon la javadoc les deux instruments de JedisConnectionFactory et LettuceConnectionFactory l'interface RedisConnectionFactory.

Ma conclusion est que RedisHttpSessionConfiguration attend un haricot de type RedisConnectionFactory mais il n'a pas pu être injecté puisqu'il y a deux haricots RedisConnectionFactory. Sur la base de cela, vous pouvez essayer simplement de supprimer le bean LettuceConnectionFactory de servlet-context.xml puisque le bean redisConnectionFactory est de type RedisConnectionFactory et est déjà créé à partir de applicationContext.xml.

J'espère que cette information pourrait vous aider à résoudre ce problème.