Problem
If have Pojo with:
#JsonFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") // Note the 'Z' for timezone
Instant date;
I want the serialized JSON be presented in different timezone based on TimeZoneAwareLocaleContext
Description
I have multi-tenan Spring (boot) MVC application where each tenant defines timezone in which she would like to get her data.
I understand I can register TimeZoneAwareLocaleContext into LocaleContext and how to do it but I struggle to understand how (if even possible) force Jackson to serialize dates with respect to the LocalContext time-zone.
I also considered using custom tenant-aware Jackson serializer but it feels there might already be an out of box solution which I'm overlooking.
Related
I faced the problem with generating React components with api-platform-generate-crud.
Model has property that is object email.
I have serializer that make my email object a string.
API endpoint is serving string.
It works for GET & POST.
When I try to generate React components error message is
TypeError: Cannot read property '0' of undefined
Looking deeper into it, looks like that generator still see my email as object not a string.
Any idea how I can force API to 'see' email property as string not object ?
The data model you define is authoritative. Types in the Hydra documentation reflect the ones in PHP classes.
Here, the email property is of type object. If you set the related data as a string somewhere, you don't respect this contract anymore. The Hydra documentation is not in sync with the returned data.
You can change the type of the email property in the Hydra documentation by decorating the api_platform.hydra.normalizer.documentation service.
But I would recommend to keep the PHP classes' structure of your entities as close as possible of the structure exposed through the API.
Your classes should reflect the output of the API. You can use custom data providers to deal with more complex data structure (ex: ORM entities) before hydrating the structure to expose.
I am building a symfony2 app where the user can choose her timezone. I made the neseccary model/form changes to store a timezone field in the User object.
To apply the timezone inside a specific controller action I can just use:
$user = $this->get('security.context')->getToken()->getUser();
date_default_timezone_set( $user->getTimezone() );
Is there a way to do this without having to modify every controller/action?
This is an old question but the same answer still applies.
date_default_timezone_set should not be used in this manner. If you create a Datetime instance, the timezone will always be set to symfonys default timezone. This will lead to inconsistencies, I wish you the best of luck finding them :)
Basically, you should create a custom DateTime type that handles conversion of timezones. Additionally, if you really want different timezone on your server, set the timezone in config/parameters.yml so php handles all dates in the timezone you need.
parameters:
default_timezone: Europe/Warsaw
There's a nice tutorial here that will show you everything you need to know.
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?
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);
...
}
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.
For Spring Boot 2.x.x
#RequestMapping
public String foo(TimeZone timezone) { ... }
It works Perfectly.
I have a situation which keeps coming up all the time when I think it's over. It's a ASP.NET project but I am not using ASP.NET AJAX elemets and any server side elements in design part. I am using ASP.NET to handle database operations and using jQuery elements in design, also using only jQuery AJAX to send and receive data from UI.
I have a method which runs when an ajax call is made and returns an object class with a DateTime element in it. I need to use what returns in a javascript function to show on the screen. I don't want to use JSON.NET or anything else to serialize the returning class beacuse ASP.NET does all the conversions when I return an object class, itself already.
So, my problem is I am getting a long date format which is not compatible with any javascript function and none of moment.js or date.js libraries supporting that format. The output of the datetime asp.net object in javascript is like:
"Sun Aug 11 2013 00:00:00 GMT +0300 (Turkey Daylight Time)"
I looked for some info about that for days and didn't find any questions or articles explaining how to cast returning datetime properly. May be not looking for the right thing...
I know that I can create a JSON string and send that class' values with it. I've been there. But my head starts hurting when I start to question the logic of asp.net automatically serializing returning classes and returning a non useful datetime object.
So, I decided to hear your opinions on that matter. What is the best way of dealing datetime conversion issues in asp.net?
I can change the DateTime object to a simple string and get the value as string and cast it to datetime in asp.net and return the same class with a string like a date object, but that is creating other casting problems in javascript side (DD/MM/YYYY and MM/DD/YYYY issues).
I can look for a way to properly cast the returning datetime format of asp.net to javascript form (which I believe is after a lot of research is quite impossible)
I can create my class which would include a long int object and cast (serialize) that datetime object to JSON format before sending as a return call in asp.net method.
Which one of these is better and why, and is there another, better way to do this?
Thanks...
In Grails, one can 'bindData' in controller:
Book b = new Book()
bindData(b, params)
What if I have a date field with specific format (e.g. yyyy-MM-dd) from user input? In Spring, we can use registerCustomEditor(). How about Grails?
With Grails 1.1.1, you can implement a PropertyEditorRegistrar and use that to specify a format. See http://grails.1312388.n4.nabble.com/Grails-1-1-1-change-in-binding-date-properties-td1323105.html
Have you already come across the Extended Data Binding Plugin?
From the documentation on the site, it appears to offer both aspects which you are referring to
Allow customization of the DataBinder that will be used to parse user-defined input and populate objects (typically domain objects) with custom PropertyEditors on both application-wide and controller-specific levels.as String.
Extend controllers with dynamic methods to allow data binding and bean wrapping.