I'm implementing spring-session inside my JEE project with Redis. The HttpSession is being saved and updated on my Redis server and I'm able to use it in case of a node failover.
The thing is, my session scoped beans are not getting saved with the session in Redis, and because of this I can't use on a cluster, since the user needs the information stored on the bean to use a lot of functions (steateful).
Am I missing something? I couldn't find a lot of information about this, and since I'm new to Spring, it gets confusing. Is the bean (or can it be) stored with the session in Redis? Here's my implementation:
web.xml:
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>bootstrap</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>
javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE
</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
<welcome-file-list>
<welcome-file>login.faces</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>com.exception.InvalidPasswordException</exception-type>
<location>/ErroServlet</location>
</error-page>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/login.faces</location>
</error-page>
<error-page>
<!-- Missing login -->
<error-code>401</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<!-- Forbidden directory listing -->
<error-code>403</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
<error-page>
<!-- Uncaught exception -->
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<!-- Unsupported servlet method -->
<error-code>503</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<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>
<filter>
<filter-name>UserCheckFilter</filter-name>
<filter-class>com.servlet.UserCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UserCheckFilter</filter-name>
<url-pattern>/admin/*</url-pattern>
<url-pattern>/dashboard/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>UserLogCheckFilter</filter-name>
<filter-class>com.servlet.UserLogCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UserLogCheckFilter</filter-name>
<url-pattern>/login.faces</url-pattern>
</filter-mapping>
<filter>
<filter-name>AWSXRayServletFilter</filter-name>
<filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class>
<init-param>
<param-name>fixedName</param-name>
<param-value>app</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>AWSXRayServletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
session.xml:
<context:annotation-config/>
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />
<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="127.0.0.1" p:port="6379" />
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.3.RELEASE</version>
<type>pom</type>
</dependency>
Controller: (The abstract controller implements Serializable)
...
@Named
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Controller extends AbstractController {
// EJB to access database using JPA
@EJB(mappedName = "java:global/app/app-ejb/ControllerService!com.service.ControllerService")
ControllerService controllerService;
// A class with my JPA Entity used in the form and some other properties
private FormFields formFields;
...