0

MVVM and Validator (or Constraint)

asked 2012-05-05 16:13:30 +0800

juergenmw gravatar image juergenmw
79 1

Hi

Right now I didn't have any issues in learning how to use ZK - I focused on MVVM mainly.
But lately I spent some time reading about validators and played around with test code and to be honest - I can not see a "clear path" how to use form validation.

As far as I can tell MVVM uses valitators to validate input - VM provides a instance of AbstractValidator and it does all the validation like explained here. There are some pros and cons with property bindings and the "save before" approach - well, not to hard to understand but a "lot" of code to write.

On the other side there is an "easy" way to get form validation by applying
constraint='.....' to an input field - realllyyyy easy.

So here a few questions:

1.) Why are there no examples with MVVM and constraint="..." - also see nr. 2
2,) It seems to me the validator is much more effort - think of preventing an empty textfield

<textbox constraint="no empty"/>

versus

<textbox value="@load(...) @validator(vm.quantityValidator)" />

plus additional java code for validating the same basic thing

	
        public Validator getQuantityValidator(){
	    return new AbstractValidator(){
	        public void validate(ValidationContext ctx) {
	            Integer nr = (Integer)ctx.getProperty().getValue();
	            if(nr==null || nr<=0){
	                addInvalidMessage(ctx, "must be larger than 0");
	            }
	        }
	    };
	}


3.) Is there an way to prevent a command execution (eg onSave) when "constraint" still has errors or does MVVM ALWAYS have to have a server side validator implementation in MV?

Maybe I am just completly on the wrong path ... any comments?

BR
juergenmw

delete flag offensive retag edit

6 Replies

Sort by ยป oldest newest

answered 2012-05-05 17:11:19 +0800

antonko gravatar image antonko
15

updated 2012-05-05 17:17:41 +0800

Hello juergenmw,

I have some thoughts regarding 2nd question: as far as I understand from Javadoc for ClientConstraint some validations are performed on a client side. It is faster and lighter but generally it's not reliable way because an attacker can easily change validation logic or disable it all.

However I join your question and would like to know the difference between server side constraints and validators (which are always server-side, as far as I understand)

Thank you,
Anton.

link publish delete flag offensive edit

answered 2012-05-06 07:44:07 +0800

Matze2 gravatar image Matze2
773 7

Currently I use the following approach:
- use constraints where possible for single field validation; I also do not see the advantage here
- use form binding which triggers another validation at submit phase (i.e also the constraints are revalidated, similar to DataBinder.saveAll())
- for more complex validations (i.e. relations of input fields) I use the new validator approach (you have the chance to show mulitple error messages with one validation); this validator is only connected with form binding (i.e. submit)

But I am also missing a general statement especially for simple cases like "no empty" or "no negative".

link publish delete flag offensive edit

answered 2012-05-06 08:04:05 +0800

juergenmw gravatar image juergenmw
79 1

Hi antonko

Sure - client Side validation is insecure by design.
I guess I was confused because there is "SimpleConstraint" and "ClientConstraint" which indicated (to me) that simpleConstraint is done server side which is wrong - unfortunately I did not read the javadoc at length, my mistake.

Regarding your question - I would assume (please correct me) that server side constraint just "checks" for the given format/content and behaves like client constraint and returns a message (or JS code) which is being displayed. It can be used when client and server's implementation (eg. regexp) differ.

Whereas validator (server side only) has some automatism to store error messages to the binder (see Validation Message Holder). The messages can be accessed by the client via field id and validationMessages="@id('vmsgs')"
Maybe someone else can explain it better.

I would like to break down my initial question - why is there no "default" server side validation implementations?
I'd assume 90% of the fields follow the same rules:

* min/max int
* min/max string length
* no empty
* email
* ....

Despite ZK's validator approach is quite flexible those default checks will be implemented over and over again (even though they are not very complicated to implement). E.g. as a beginner I was simply searching for a "EmailValidator" implementation under org.zkoss.*

BR
juergenmw

link publish delete flag offensive edit

answered 2012-05-07 15:56:48 +0800

juergenmw gravatar image juergenmw
79 1

updated 2012-05-07 16:55:32 +0800

@Matze2 - when is it possible to use constraint? Since it seems this is done on client side this is never a secure way to validate input (meaning: protecting Bean/DB from disallowed values). I assume you just use it to get the user message immediatly, real validation is done before saving the middle object/bean.

What was the standard way of server side validation before ZK6 (MVVM) when only using MVC?

link publish delete flag offensive edit

answered 2012-05-07 18:59:24 +0800

Matze2 gravatar image Matze2
773 7

I don't think that it is only checked on the client side,see SimpleConstraint.validate():

	public void validate(Component comp, Object value)
	throws WrongValueException {
		if (value == null) {
			if ((_flags & NO_EMPTY) != 0)
				throw wrongValue(comp, MZul.EMPTY_NOT_ALLOWED);
		} else if (value instanceof Number) {
			if ((_flags & (NO_POSITIVE|NO_NEGATIVE|NO_ZERO)) == 0)
				return; //nothing to check

			final int cmp = compareTo((Comparable)value,
				Classes.coerce(value.getClass(), null, false)); //compare to zero
			if (cmp > 0) {
				if ((_flags & NO_POSITIVE) != 0)
					throw wrongValue(comp, getMessageForNumberDenied());
			} else if (cmp == 0) {
				if ((_flags & NO_ZERO) != 0)
					throw wrongValue(comp, getMessageForNumberDenied());
			} else {
				if ((_flags & NO_NEGATIVE) != 0)
					throw wrongValue(comp, getMessageForNumberDenied());
			}
		} else if (value instanceof String) {
			final String s = (String)value;
			if ((_flags & NO_EMPTY) != 0 && s.length() == 0)
				throw wrongValue(comp, MZul.EMPTY_NOT_ALLOWED);
			if (_regex != null && !_regex.matcher(s != null ? s: "").matches())
				throw wrongValue(comp, MZul.ILLEGAL_VALUE);
			if ((_flags & STRICT) != 0) {
				if (s.length() > 0 && comp instanceof Combobox) {
					for (Iterator it = ((Combobox)comp).getItems().iterator(); it.hasNext();) {
						final Comboitem ci = (Comboitem)it.next();
						if(!ci.isDisabled() && ci.isVisible() && s.equalsIgnoreCase(ci.getLabel()))
							return;
					}
					throw wrongValue(comp, MZul.VALUE_NOT_MATCHED);
				}
			}
		} else if (value instanceof Date) {
			if ((_flags & (NO_FUTURE|NO_PAST|NO_TODAY)) == 0)
				return;
			final Date date = Dates.beginOfDate((Date)value, null);
			final int cmp = date.compareTo(Dates.today());
			if (cmp > 0) {
				if ((_flags & NO_FUTURE) != 0)
					throw wrongValue(comp, getMessageForDateDenied());
			} else if (cmp == 0) {
				if ((_flags & NO_TODAY) != 0)
					throw wrongValue(comp, getMessageForDateDenied());
			} else {
				if ((_flags & NO_PAST) != 0)
					throw wrongValue(comp, getMessageForDateDenied());
			}
		}
	}

This is executed on server side.
But even if it would be only checked on client, the final validations are anyway done on the backend API again (because it may be also used by other frontend layers) or by database constraints. At least for me, security is not the important point.

link publish delete flag offensive edit

answered 2012-05-09 08:22:21 +0800

juergenmw gravatar image juergenmw
79 1

Thanks for your Reply matze. Got it and it works as expected now.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-05-05 16:13:30 +0800

Seen: 621 times

Last updated: May 09 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More