I'm trying to modify a wicket application to store the session in redis via spring-session. The session is showing up in redis, but I've run into a problem that whenever the application makes a standard wicket ajax call, the response from wicket includes an Ajax-Location header that is interpreted by wicket-ajax-jquery.js triggering a page redirect. But this only happens AFTER the first ajax call has been successful. For example, the first ajax call may look like this:
http://host:port/context/help/admin?0-1.IBehaviorListener.0-smartTable-tableArea-records-0-row-detailToggleCell-detailToggleLink&_=1636756805561
and the response headers do NOT include Ajax-Location. And then later, the next ajax call may look like this:
http://host:port/context/help/admin?1-1.IBehaviorListener.0-smartTable-tableArea-records-0-row-detailToggleCell-detailToggleLink&_=1636756906417
But the response header now includes this:
Ajax-Location: ./admin?2
and instead of just doing the ajax update to the page, the entire page redirects to the URL specified in that header because of code in src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
Digging down into the wicket-core code using the debugger, consider this where it doesn't produce the Ajax-Location header and works properly:
Step completed: "thread=ba6f07:3", org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(), line=197 bci=169ba6f07:3[1] print canCallListenerInterfaceAfterExpiry canCallListenerInterfaceAfterExpiry = falseba6f07:3[1] print freshPage freshPage = falseba6f07:3[1] print isStateless isStateless = falseba6f07:3[1] print component component = "[AjaxLink [Component id = detailToggleLink]]"
and then compare with this where it DOES produce an Ajax-Location header and doesn't work properly:
Breakpoint hit: "thread=ba6f07:7", org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(), line=197 bci=169ba6f07:7[1] print canCallListenerInterfaceAfterExpiry canCallListenerInterfaceAfterExpiry = falseba6f07:7[1] print freshPage freshPage = trueba6f07:7[1] print isStateless isStateless = falseba6f07:7[1] print component component = null
The difference being that when it doesn't work, freshPage is true and component is null.
Note: this pattern is fully functional in another similar application that I have and I’ve spent some time comparing the two. Clearly, something is missing from the original application in the app that I’m working on but I haven’t been able to identify it yet.
My redis http session config class looks like this:
import javax.annotation.PostConstruct;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;import org.springframework.session.web.http.CookieHttpSessionStrategy;import org.springframework.session.web.http.DefaultCookieSerializer;@Configuration@EnableRedisHttpSessionpublic class MyRedisHttpSessionConfig extends RedisHttpSessionConfiguration{ private JedisConnectionFactory connectionFactory; @PostConstruct public void init() { CookieHttpSessionStrategy strategy = new CookieHttpSessionStrategy(); DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); cookieSerializer.setCookieName( "SESSION" ); strategy.setCookieSerializer(cookieSerializer); setHttpSessionStrategy( strategy ); } @Bean public JedisConnectionFactory connectionFactory() throws Exception { return connectionFactory; } public void setConnectionFactory( JedisConnectionFactory connectionFactory ) { this.connectionFactory = connectionFactory; }}
my web.xml has this:
...<filter><filter-name>requestLoggingFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter><filter-name>springSessionRepositoryFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter><filter-name>myApplicationWicketFilter</filter-name><filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class><init-param><param-name>applicationFactoryClassName</param-name><param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value></init-param><init-param><param-name>filterMappingUrlPattern</param-name><param-value>/*</param-value></init-param></filter>...<filter-mapping><filter-name>springSessionRepositoryFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> ...<filter-mapping><filter-name>ariesApplicationWicketFilter</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>ERROR</dispatcher></filter-mapping>...
and my spring beans config file has this:
...<!-- The RedisHttpSessionConfiguration creates an http Filter bean with name "springSessionRepositoryFilter" which is referenced in web.xml --><context:annotation-config/><util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/><bean class="MyRedisHttpSessionConfig"><property name="connectionFactory" ref="webTierRedisConnectionFactory"/></bean><bean id="webTierRedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="${service-tier:redisSentinelMasterName}"/><property name="port" value="${service-tier:redisSentinelHostPortCsv}"/><property name="usePool" value="true"/><property name="poolConfig"><bean class="redis.clients.jedis.JedisPoolConfig"><property name="maxWaitMillis" value="5000"/><property name="maxTotal" value="50"/><property name="maxIdle" value="5"/><property name="minIdle" value="1"/><property name="testWhileIdle" value="true"/><property name="timeBetweenEvictionRunsMillis" value="60000"/><property name="numTestsPerEvictionRun" value="10"/></bean></property></bean>...
Ivy Dependencies include:
<!-- these are for redis httpsession --><dependency org="redis.clients" name="jedis" rev="2.8.1"/><dependency org="org.springframework.data" name="spring-data-redis" rev="1.7.4.RELEASE"/><dependency org="org.springframework.data" name="spring-data-keyvalue" rev="1.1.4.RELEASE"/><dependency org="org.springframework.session" name="spring-session" rev="1.2.2.RELEASE"/>
and wicket 7.5.0 and spring 4.2.8 stuff.
Anybody have any insights on what might be going on? Why after putting the session into redis (which it is showing up there, I see it (via redis-cli and keys and dump commands), most ajax calls are triggering full page redirects due to response headers from the ajax call including Ajax-Location?