62

In one of controllers in my Grails application I'm preserving a parameter value in a session variable like this:

session.myVariable = params.myValue

After that, I can access the saved value from different controllers/GSP-pages as long as I actively use the app. However, if I don't use my app for a while, even though my browser window is still open, the session variable looses it's value.

Does this happens because the session expires? I was under impression that a session lives until the browser window is still open, but apparently I was wrong.

What should I do to ensure all session variables I define in my Grails app don't expire until the browser is closed? Is there any way to set session timeout manually?

Thank you in advance for your answers!

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
curd0
  • 2,300
  • 3
  • 27
  • 32

7 Answers7

86

Another option would be modifying web.xml. Prior you must call

grails install-templates

Then edit src/templates/war/web.xml and add/modify after servlet-mapping:

<session-config>
   <session-timeout>60</session-timeout>
</session-config>

The value of session-timeout uses minutes as unit.

Stefan Armbruster
  • 39,465
  • 6
  • 87
  • 97
  • Thanks, Stefan! That's *EXACTLY* what I was looking for. I didn't realize I have to explicitly 'install-templates' to get to web.xml. I'm still a n00b in Grails :) – curd0 May 27 '10 at 21:04
  • 2
    I want to handle a session timeout as well. I just have a question about this. Configuring this in the web.xml file, what would happend once the session expires and an action from a controller is executed? Would the session.myVariable from @curd0's example will return null? Thanks! – Tomarto Feb 04 '13 at 15:14
  • 1
    It this still required for Grails 2.x? I thought `web.xml` was standard in grails apps; why is `install-templates` required? – raffian Jan 27 '14 at 20:39
  • @raffian I don't know if it is required, but it does work with grails 2.x (testing grails 2.5.4 here). grails install-templates outputs a lot of stuff but you only have to keep src/templates/war/web.xml, all the rest of src/templates can be deleted. – Colin D Apr 25 '16 at 18:17
46

Fast forward a few years... For Grails 3.0 set the session timeout with ServerProperties in the application configuration file.

grails-app/conf/application.yml

server:
   session:
      timeout: 3600  #seconds

Default value: 1800 seconds (30 minutes)

Verify the timeout for the HttpSession from a controller using getMaxInactiveInterval():

log.println "Timeout: ${session.getMaxInactiveInterval()} seconds"

Output --> Timeout: 3600 seconds

Update: Edited configuration for changes in Grails 3.1

Dem Pilafian
  • 5,625
  • 6
  • 39
  • 67
  • 2
    Actually it is now server: session: timeout: 3600 – Kimi Feb 01 '17 at 10:54
  • how to disable session timeout? @DemPilafian –  Mar 20 '17 at 13:41
  • 2
    @akiong, I haven't tried it, but according to the documentation, `A zero or negative time indicates that the session should never timeout.` – Dem Pilafian Mar 20 '17 at 17:56
  • For Grails 5 it is `server.servlet.session.timeout=8h`. It changed as the property was change in the underlying spring-boot version. See https://stackoverflow.com/questions/40974955/spring-boot-java-config-set-session-timeout – Marc Schmid Jun 30 '23 at 15:28
7

The current grails (2.x) have a very odd design approach to setting the session timeout. None of the prevailing ideas are great:

  1. comment out "//session Timeout" section the within the WebxmlGrails Plugin and add "sessionConfig.sessionTimeout=" to Config.groovy

  2. grails install-templates, remove session-timeout from web.xml, add timeout in WebXmlConfig.groovy

  3. wait for a fix. :/

A co-worker came up with the following code that works well for me and will do until a real solution is built into grails core.

Simply add the following to the bottom of your config.groovy file and then set the appropriate timeout.

grails.war.resources = { stagingDir, args ->
  def webXML = new java.io.File("${stagingDir}/WEB-INF/web.xml")
  webXML.text = webXML.text.replaceFirst("<session-timeout>30</session-timeout>", "<session-timeout>90</session-timeout>")
}

My I suggest that the correct solution is to allow a single line in the Config.groovy file:

session.timeout = 90;

Cheers.

WeMakeSoftware
  • 9,039
  • 5
  • 34
  • 52
3

With Grails 3.1.x session-timeout is deprecated. The correct property in application.yml is:

server:
    session.timeout: 7200
1

here is a better working solution. go you your grails home directory and find Example: E:\grails-2.3.8\src\war\WEB-INF\web3.0.template.xml edit the session time out value to desired values:

Example: enter code here 90

1

I could be wrong, but I'm pretty sure Grails uses the sessions associated with your application container. If you're using Tomcat, for example, you can specify the length of a session.

Tutorial for changing Tomcat session length.

Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406
  • 1
    Grails does use the container's sessions, but just overriding the default doesn't work because grails will generate a new servlet specific web.xml that will override the default. – codemonkey Aug 28 '15 at 18:44
0

For Grails 3 application, modifying the Application.groovy worked for me:

package foo

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.apache.catalina.Context
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
import org.springframework.context.annotation.Bean

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        GrailsApp.run(Application, args)
    }

    @Bean
    EmbeddedServletContainerFactory containerFactory() {
        TomcatEmbeddedServletContainerFactory containerFactory = new TomcatEmbeddedServletContainerFactory()

        containerFactory.addContextCustomizers(new TomcatContextCustomizer() {
            @Override
            void customize(Context context) {
                int oneWeekInMinute = 7 * 24 * 60
                context.setSessionTimeout(oneWeekInMinute)
            }
        });

        return containerFactory
    }

}
Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121