Vaadin & Spring Boot - Alternative translations within ValidationMessages.properties are not picked up - validation

I tried to use BeanFieldGroup<Entity> in Vaadin Spring Boot, with javax.validator and Hibernate validators.
#NotBlank(message = "{may.not.null}")
#Column(name = "name", unique = true)
private String name;
and I created two files: ValidationMessages_en.properties:
may.not.null=not null
and ValidationMessages_fr.properties:
may.not.null=non null
But even when I change the language to French, the validator message is still from ValidationMessages_en.properties.
Have any of you any idea about this, please?

The BeanFieldGroup creates the BeanValidator with the locale, which is set to the component under validation. Your question does not mention how you create the text field for the name property, but let's assume that you create it this way:
TextField nameTextField = new TextField("Name");
The important factor here is to make sure that the nameTextField has correct locale before you bind the properties with BeanFieldGroup (you can check the locale with nameTextField.getLocale()).
So, try to configure your TextField to use the session locale like this:
nameTextField.setLocale(UI.getCurrent().getLocale());
This piece of code takes the locale from the request ("Accept-Language" request header) and sets it to the field -> the BeanFieldGroup will then create BeanValidators with the correct locale and the validation messages are localized (this happens in BeanFieldGroup#configureField).
However use this code only to check that the problem is really only in that your text field does not have correct Locale. It really does not mean that you have to set the Locale for each and every field out there... That's because in Vaadin (at least in Vaadin 7) the session (request based) Locale should be inherited by component from the parent. So if you add TextField to the Layout, then the TextField inherits the locale of the Layout, the Layout inherits it from the View and so on (all the way up to UI.getCurrent().getLocale() - so check that you have desired locale there). Since the inheritance happens during addComponent() call, it's my guess, that, maybe, in your case, it would be enough to call the addComponent() method (where you are adding the TextField to the layout) before you actually use the BeanFieldGroup binding.
More info about your problem here: Remember to set the Locale
Note: I tried to code your issue right now, I faced the same problem as you had and resolved it by moving the addComponent() call before the BeanFieldGroup.

Related

Spring boot: Override property value

Into my application-pre.properties file there's coded this property:
scheduler.url-backoffice=http://${BACKOFFICE_SERVICE}:8080
In order to fill it, I'm using -Dspring-boot.run.arguments=--spring.config.additional-location=scheduler-config.properties.
scheduler-config.properties:
BACKOFFICE_SERVICE=localhost
scheduler.url-backoffice=http://localhost:8081
I need to set BACKOFFICE_SERVICE property, otherwise spring doesn't start. So, it means that scheduler.url-backoffice comes to http://localhost:8080.
I 've added another line after that in order override its value.
My surprise is its value is not changed. I mean, scheduler.url-backoffice's value is http://localhost:8080 instead of http://localhost:8081.
I'm not able to change application-pre.properties content file.
Use multiple application properties files.
One can ship in the jar;
this contains the defaults.
For me, defaults translates to either the prod values,
if there is only one set of prod values,
or the developer local values (which should cause failures in production).
The second file contains the environment specific property values that
override the defaults.
You must change your startup values to achieve this.
Here is an example:
-Dspring-boot.run.arguments=--spring.config.additional-location=scheduler-config.properties,local-scheduler-config.properties
Edit: in response to "still not working".
It seems like you need much more than the "simple" approach I described above.
For that,
check out section 24. Externalized Configuration in the Spring Boot Reference Guide.
There are many techniques to override configuration values;
all are covered in the reference guide.

Spring MVC: how to get case-insensitive ordering from Pageable

I am trying to support case-insensitive ordering in my Spring MVC app when users click on the column headings on my web page. When the page is rendered a Thymeleaf extension creates an anchor and the href is the current URL with some parameters supported by Pageable: i.e. page, size and sort.
The sort=propertyName,ASC format works fine, but I can't find out how to say that the sort should be case-insensitive from the URL. I can do it in code easily enough but the standard Pageable support doesn't seem to support it.
After some debugging it appears that the standard framework org.springframework.data.web.SortHandlerMethodArgumentResolver just doesn't have any support for org.springframework.data.domain.Sort.Order.ignoreCase.
I'm somewhat bemused about this, and am wondering if there's a good reason why?
I can look into creating my own SortHandlerMethodArgumentResolver class, and make it parse ASCI|DESCI (to mean case-insensitive), and ASCS|DESCS (to mean case-sensitive) and produce the appropriate Sort object, but this strikes me as quite a bit of work and a serious "code smell".
I can't be the first person to stumble across this. Does anyone have any advice?
I think the only option is to implement your custom SortHandlerMethodArgumentResolver. The documentation has brief guideline for this http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
To customize this behavior extend either SpringDataWebConfiguration or
the HATEOAS-enabled equivalent and override the pageableResolver() or
sortResolver() methods and import your customized configuration file
instead of using the #Enable-annotation.
For the format I would make it a comma-separated string of 3 elements: field name, direction, ignoreCase flag. Something like this:
sort=name,ASC,ignore
The last element is optional so it's possible to have:
sort=name,ASC
which would mean that ignoreCase is false.
Also it should be possible to specify only field name like:
sort=name
which would mean the default direction of ASC and ignoreCase is false.
The only issue is if you want to pass ignoreCase flag you must pass the direction which should not be a big problem I think.
Hope this helps!
Btw here is a JIRA item for this improvement https://jira.spring.io/browse/DATACMNS-658 (Extend SortHandlerMethodArgument resolver to be able to detect the request for ignore-case)
If somebody is using Spring Data Commons 2.3 RC1 or later and looking for query params, use following. (Ignore case in sorting is available out of the box in Spring Data Commons 2.3 RC1 and later)
sort=name,ASC,ignorecase

sfWidgetFormInputCheckbox do not work properly

I have a problem with a sfWidgetFormInputCheckbox. It do not save false in the database when the checkbox is unchecked.
In my schame my field is a boolean, and i don't have bug in the value displayed.
Set the default value like this : $this->setDefault('status', false); don't work either.
My widget :
$this->widgetSchema['SUSPENSION_TEMP'] = new sfWidgetFormInputCheckbox();
$this->validatorSchema['SUSPENSION_TEMP'] = new sfValidatorBoolean(array('required' => false));
The default :
$this->setDefault('SUSPENSION_TEMP', false);
Any ideas ?
Edit:
It save 1 when the checkbox is checked. And do not change the database value when you unchecked and save. So once you checked once, value is always 1 in database (true for my code).
Edit2:
I have two clues to add. If the field is an integer in the schema.xml, both values work, bu we got a poblem on value displayed (checkbox checked qih the 0 value). Here, he field is a boolean.
The setter receive two kinds of value, 'on' when checkbox is checked and true when it's not. I tried to set default value to false in form, and to overide he setter. Both don't work.
I mean the setter work, but for an unknown reason the basic seer is called right after with a wrong value.
Edit3:
Ok, i understand part of the problem. The setter is not called, when the checkbox is unchecked. I thought it was because, m code displayed a var_dump(). It was because later i copy the old version of this object in archive purpose.
But symfony should detect that the field has been rendered and it doesn't. I don't know why. I know why in html, but obviously symfony should be able to tell himself "hey, i add a checkbox here".
Is there an elegant way o do this, or should i checked it by hand ?
The problem came from my form handling. My legacy code, did no render all fields (ex : some stamp field, updated by a behavior). It was using fromArray, then save. This update only the fiels rendered.
The traditionnal symfony form, give null to all non-rendered fiels in order to chcuk for required validation.
So you need to check by yourself and set to 0, when you are using a fromArray then save. Still, i find the form->save really dumb, because you need to send useless(in this case) or confidentials data to your client in order to use it.

Allow non filled fields

I have a model for an ASP.NET MVC view containing several properties:
Subject
Message
Id
While subject and message are required, Id isn't required (it's hidden and only set
for an existing entry). Unfortunately, MVC validates it as required ( The If field
is required) even though I haven't set the Required attribute.
Has someone a solution? Haven't found a solution here, maybe just searching wrong...
Kind regards,
Sascha
If Id is an Int... you can try making it Int? (nullable Int).
If it is nullabe, I think MVC will not validate it.
Another way, would be place a default value in that hidden, lets say a "-1"... and on the controller you can check it.
By default, ASP.Net Mvc will treat non-nullable properties as 'required' - even if you do not add the [Required] attrtibute to the property. If your id is of type int - it is not-nullable and therefore required.
You have basically two options:
Change your Id property to int? - ie a nullable int.
Change the default setting for MVC to not regard non-nullable attributes as required.
Option 1 is straight-forward. For option 2 add the following to the Application_Start method in your global.asax
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = true;

Silverlight 4: Localization of built-in data annotation validation exceptions

I would like use data annotations to handle validation in my Silverlight app. The built-in validation attributes (primarily StringLength and Required) are great, and make life very easy. However, they seem to have one critical flaw. If my locale is set to fr-CA, for example, the validation exceptions are still in English - 'The Name field is required', 'The field Name must be a string with a maximum length of 20', etc.
This is a major problem. It means that if I want localized error messages for the built-in validation attributes, I have to manually add ErrorMessage/ErrorMessageResourceType to every validation attribute on every validatable property in my business layer, and manually add translated strings for every error message.
So... am I missing something here? Is there a way to automatically have the built-in validation attributes localized? Or some other easier way of doing this? Or am I just completely out of luck, and stuck with the manual route?
Any comments or thoughts would be appreciated.
Ok, I got around this by simply subclassing the built-in validation attributes. Problem solved!
internal class LocalizedStringLengthAttribute : StringLengthAttribute
{
public LocalizedStringLengthAttribute(int maximumLength)
: base(maximumLength)
{
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, LanguageResources.Resource.Error_StringLength, name, MaximumLength);
}
}

Resources