Spring MVC: Set property to null when bind fails - spring

Is it possible to configure Spring to set the target property to null when binding fails?
For example, my bean has a date property which can have a pre-existing value when the form is displayed. If the user enters an invalid date, I want the property to be set to null; currently it retains its previous value.
I still want the binding error of course, so I can display an error message.
I'm hoping there's a general configuration solution for this (ie. I don't want to just write code to deal with each field manually!).
Background: Retaining the old value causes odd behaviour in subsequent custom cross-field validation. Setting the property values to null would tell this validation not to execute.

Related

Sitecore Item Validators

I created an item validator with the validation rule template. I'm using it to check if one field for a date is after another field for a date following this tutorial: https://sitecorejohn.wordpress.com/2010/03/17/validate-that-the-value-of-one-datetime-field-follows-another-with-sitecore. For some reason the item that is pulled with GetItem() in my validator does not have the change that the content editor has made until the item is saved. I thought Sitecore.Data.Validators.BaseValidator.UpdateItem would take care of this but it seems that my control to validate is null. That makes sense since it is an item validator instead of a field validator but that means that if this fires off on blur content editors may see false error messages or not see error messages when they should. I'm also running into an issue where my Evaluate method is firing twice on save; once before the item is actually saved so GetItem() returns with the non-updated values and once after save which has the expected values. If anyone has any insight as to why this might be happening I'd like to know. I have a feeling that the validator executing twice on save might be a config issue but I didn't see anything very obvious in the pipeline.
To get the new value of the field that's being validated you can use BaseValidator's
GetControlValidationValue();

Get value of editbox of type date/time

I try to get the value of an editbox of type Date/Time. If I test it with
getComponent("dateField").value
or
getComponent("dateField").getSubmittedValue();
and print the output to the console. It always returns "null" if the field is empty or
the field does not contain a valide date. Because of this I can't differ between invalide input and empty input.
Is there a way to get the information if the field is empty?
It depends on the refresh phase you're testing.
getValue() will always return blank, because only content that can be converted to the underlying data type will be passed to it. Even if you disable validation, converter checks still run, because serious errors will occur if you try to put "this is not a date" into a Date/Time.
getSubmittedValue() will always be null if you're checking in Invoke Application or Render Response phases. That's because during the Update Model Values phase, the submittedValue property is passed to the value property and the submittedValue property nulled.
If you're checking in a validator, the text value entered by the user has not yet been checked against validation rules (validation) or that it can be converted to the right data type (conversion), so getValue() will return the value stored last time round and getSubmittedValue() will give the string value (e.g. "this is not a date").
So the answer is you should be able tell whether the field is empty in a validator, but bear in mind custom validators only run if you also have a required validator.

Validator skipped when input is removed in client – is this as per JSF specification?

I have a page with an input text component marked as required="true" and having a custom Validator in server side.
Now as a client, I submit the page without the HTML element rendered by that component (this can be easily achieved by removing the element from the DOM tree using browser's builtin DOM element inspector). The form is successfully submitted, without the server side validation of this required component.
Is this as per JSF specification? Is there a way to specify that the validators in the page are to be executed even if the posted page do not contain them?
This is indeed as per the specification. Here's an extract of relevance from UIInput#validate() javadoc (emphasis mine):
Retrieve the submitted value with getSubmittedValue(). If this returns null, and the value of the ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUE context-param is true (ignoring case), examine the value of the "required" property. If the value of "required" is true, continue as below. If the value of "required" is false or the required attribute is not set, exit without further processing. If the context-param is not set, or is set to false (ignoring case), exit without further processing. (This indicates that no value was submitted for this component.)
An empty input will send an empty string, not null. A complete absence of the input will send null, not empty string.
You can thus disable the observed behavior by adding the following context parameter:
<context-param>
<param-name>javax.faces.ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUE</param-name>
<param-value>true</param-value>
</context-param>
Note that this context parameter is new since JSF 2.3 and backported into Mojarra 2.2.16, 2.1.29-10 and 1.2_15-06. It is not supported in older versions. See also JSFSPEC-1433 and the expert group discussion about this issue.
Whether that is harmful or not depends on the business logic. A decently designed model (business logic and/or data model) which doesn't consider null as expected case would cause a null pointer exception elsewhere, or a SQL constraint violation (NOT NULL), which will usually end up in a HTTP 500 error response. But if the model actually considers null as an expected case, then it's likely a fault in the model. The view (the JSF page), intented to merely present the model, can then do little against it.
If the business logic or data model can really not be altered to consider null as an exceptional case (i.e. never assume/accept the given value as null), and you happen to use JPA, then your best bet is to add a #NotNull on the property. Whilst JSF will bypass validation on it, JPA will still validate it, causing still an exception and a HTTP 500 error. I'd in this case only wonder why the DB column doesn't have a NOT NULL constraint in first place. Alternatively, do class level validation.
Noted should be that MyFaces logs a warning like below on this:
Mar 16, 2016 8:55:52 AM org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils decodeUIInput
WARNING: There should always be a submitted value for an input if it is rendered, its form is submitted, and it was not originally rendered disabled or read-only. You cannot submit a form after disabling an input element via javascript. Consider setting read-only to true instead or resetting the disabled value back to false prior to form submission.
Component : {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId: /test.xhtml][Class: javax.faces.component.html.HtmlBody,Id: j_id_5][Class: javax.faces.component.html.HtmlForm,Id: j_id_6][Class: javax.faces.component.html.HtmlInputText,Id: j_id_7] Location: /test.xhtml at line 22 and column 33}

Using Spring:bind to set value to java object

I am using spring's bind tld to map a textbox to the java model object's property. When no value is entered in the text box and submit action is done, what value will be set in the model property? property is declared as type String. I am not setting any default value to the text box. Is empty value set or "" is set?
Submitted form values which are of type String are by default submitted as "".
You can register Spring's StringTrimmerEditor to ensure that empty values are converted to null if you like.

rememberMe occurs randomly without fiddler

ASP.net MVC 3 out of the box forms authentication
when certain users on certain browsers try and authenticate they get the following error
Server Error in '/MVC' Application.
--------------------------------------------------------------------------------
The parameters dictionary contains a null entry for parameter 'rememberMe' of
non-nullable type 'System.Boolean' for method 'System.Web.Mvc.ActionResult
LogOn(System.String,
System.String, Boolean, System.String)' in 'RipsMVC.Controllers.AccountController'. An
optional parameter must be a reference type, a nullable type, or be declared as an
optional parameter.
Parameter name: parameters
the problem is its not all the time but whenever i turn on fiddler2 it automatically works so i have no clue what the root cause is .
I don't think it related to fiddler, maybe you need to make rememberMe with [DefaultValue(false)] or make it a bool?.
Anyway, you can setup a breakpoint and check the request body (using Request.Forms) to see the difference with/without fiddler.
Is remember me a checkbox on the form? HTML says that checkbox values are only submitted if they are checked. So if it is unchecked, you need to send a hidden field with a false value. Using MVC #Html.CheckBox should do this automatically. However, if your HTML just renders out a single checkbox, then it might not be submitted to get a false value on the server.

Resources