Getting timezone information from request in Spring 4.0
Asked Answered
T

3

10

There is a new feature of getting timezone information in web request object. See 16.9.1 section in http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/mvc.html#mvc-timezone

But I'm unable to resolve that how can we get the timezone information from request or which method should I use to get the timezone information?

After looking & following the source code at https://github.com/spring-projects/spring-framework/blob/v4.0.7.RELEASE/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java#L242, I tried to print it manually

println WebUtils.getSessionAttribute(request, SessionLocaleResolver.class.getName() + ".TIME_ZONE")

Any help?

Thiouracil answered 29/12, 2014 at 12:44 Comment(0)
U
30

Simply add a method argument of the type TimeZone to obtain it.

@RequestMapping
public String foo(TimeZone timezone) { ... }

That should do it.

If you really want to do it yourself use the RequestContextUtils.getTimeZone(request) method.

@RequestMapping
public String foo(HttpServletRequest request) {
    TimeZone timezone = RequestContextUtils.getTimeZone(request);
    ...
}
Uyekawa answered 29/12, 2014 at 14:28 Comment(6)
Thank you Denium for response. Using your solution, I'm getting null value so do I need to configure something else?Thiouracil
The support depends on the TimeZoneAwareLocaleContext how to set/configure that isn't clear to me (yet). But basically that uses the mechanism as used by Spring to set/determine the TimeZone. I would btw expect that you would have received the default timezone for your machine/server. Are you using <mvc:annotation-driven /> in your configuration?Uyekawa
No actually, I've set any special configuration for this. I'm using this in a Grails application.Thiouracil
Ah I missed that part. The fact that you get null makes me believe that the older annotation driven pieces are used instead of the new ones. The newer shouldn't return null (when used as a method argument) but give you the default if no other timezone could be found.Uyekawa
Okay, I'll try that solution.Thiouracil
I recommend reading RequestContextUtils.getTimeZone() documentation before using it. It falls back to the system time zone when it can't be determined basing on requestBolshevism
C
4

For Spring Boot 2.x.x

@RequestMapping 
public String foo(TimeZone timezone) { ... }

It works Perfectly.

Carew answered 24/6, 2020 at 7:13 Comment(1)
Still works for Spring Boot 3.x.xLinzy
K
3

I looked into this a bit and one problem is that there isn't a default TimeZone set, which seems like an oversight; RequestContextUtils.getTimeZone(request) should return the server's time zone if nothing else is available.

That's easy enough to fix; add a dependency injection in BootStrap.groovy for the "localeResolver" bean and some code to set the default time zone in the resolver:

class BootStrap {

   def localeResolver

   def init = {
      if (!localeResolver.defaultTimeZone) {
         localeResolver.defaultTimeZone = TimeZone.getDefault()
         // or hard-code to a known instance, e.g. TimeZone.getTimeZone('America/New_York')
      }
   }
}

There's not much documented about working with TimeZones in the Spring reference docs; there's actually a lot more information in the comments of the original feature request from 2005.

Grails overrides the default LocaleResolver implementation of AcceptHeaderLocaleResolver (which has no support for TimeZone) and configures a SessionLocaleResolver instead. This looks for a locale first in the session, then for a default value set on the resolver (by default null - it's not initialized by Grails), and finally it calls request.getLocale(), which checks the Accept-Language header. This is commonly set, as having localized text is a good thing. Additionally a LocaleChangeInterceptor is configured, which looks for a "lang" param to suppport changing the Locale. But there are no conventions for passing time zone information from the client.

The time zone id seems to me like something that you would ask for during user registration and store in the database with other profile information. Then when they authenticate, you can use the stored value if it exists and set it in the session where the LocaleResolver will find it, e.g.

import org.springframework.web.servlet.i18n.SessionLocaleResolver

...

session[SessionLocaleResolver.TIME_ZONE_SESSION_ATTRIBUTE_NAME] =
    TimeZone.getTimeZone(user.timeZoneId)

It is possible to get the user's local time and TimeZone in JavaScript and send it to the server via Ajax. For some examples see the links in this answer.

Kollwitz answered 29/12, 2014 at 23:14 Comment(1)
Thank you Burt for taking time. Previously for older Grails based project we are using the javascript based approach to make an ajax call to set timezone for current user. I though the latest version have that support for auto getting timezone. But according to your description there is actually no way right now to directly get the timezone from request.Thiouracil

© 2022 - 2024 — McMap. All rights reserved.