Use jquery remote validation with struts2


Written on April 15, 2008 – 3:39 pm | by mpayne

I feel that jquery’s validation plugin gives a much better UI treatment than the struts client side validation.  In addition, there are case where one does not want to pay any Dojo penality.

To make a remote (server side) validation call, the server must return a true/false JSON response.  There is a Struts 2 JSON plugin , however in this then response needs to be a plain “true”/”false” answer, not attribute name = “{ “response”: true}.  Because of this, the Struts2 built-in “stream” result seems to make the most sense.

The xml configuration for such an action may look something like:

<package name=”ajax”  extends=”default” namespace=”/ajax“>

<interceptors>
<interceptor-stack name=”slimStack”>
<interceptor-ref name=”exception” />
<interceptor-ref name=”alias” />
<interceptor-ref name=”servletConfig” />
<interceptor-ref name=”prepare” />
<interceptor-ref name=”chain” />
<interceptor-ref name=”currentUserAware”/>
<interceptor-ref name=”staticParams” />
<interceptor-ref name=”params”/>
</interceptor-stack>
</interceptors>

<default-interceptor-ref name=”slimStack” />
<action name=”validPassword” class=”com.something.security.ui.action.RemotePasswordValidation”>
<result type=”stream“>
<param name=”contentType”>text/html</param>
<param name=”inputName”>inputStream</param>
</result>
</action>

</package>

Note that if you are using Sitemesh, you will want to make sure that these type of responses do not get decorated, because of this I put this action in own namespace (/ajax) and Sitemesh is configured to exclude
<pattern>/ajax/*</pattern>.

For the action to produce a stream reponse, it simply needs to return an InputStream.
example:
public class RemotePasswordValidation {

public RemotePasswordValidation() {
uberPattern = Pattern.compile(”^(?=.*(\\d|[^a-zA-Z\\d]))(?=.*([a-z]|[^a-zA-Z\\d]))(?=.*([A-Z]|[^a-zA-Z\\d]))(?!.*\\s).{6,12}$”);
}

private InputStream inputStream;
private Pattern uberPattern;
private String password;
private Boolean valid = false;

public Boolean isValid() {
return valid;
}

public InputStream getInputStream() {
return inputStream;
}

public String execute() {
valid = validPassword(getPassword());
inputStream = new java.io.ByteArrayInputStream(valid.toString().getBytes());
return Action.SUCCESS;
}

public boolean validPassword(String password) {
boolean result = false;

if (password != null) {
if (password.trim().length() >= 6) {
if (uberPattern.matcher(password).find()) result=true;
}
}

return result;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

The actual definition in javascript might look something like the following:

<script type=”text/javascript”>
<!–
$().ready(function() {

$(”#password”).focus();

$(”#passwordChange”).validate({
rules: {
password: {
required: true,
minlength: 6,
remote: “${base}/ajax/validPassword.action”
},
confirmPassword: {
required: true,
minlength: 6,
equalTo: “#password”
}
},
messages: {
password: {
required: “Provide a password”,
rangelength: jQuery.format(”Enter at least {0} characters”),
remote: jQuery.format(”{0} does not meet password policy requirements.”)
},
confirmPassword: {
required: “Repeat your password”,
minlength: jQuery.format(”Enter at least {0} characters”),
equalTo: “Enter the same password as above”
}
}
});
});
–>
</script>
Screen shot of running example

Other thoughts?

  • No I didn’t have to resort to server side validation for just testing a password against a regex pattern.  There are certainly many ways to skin the cat, but this provides an example of remote jquery validation that could be extended for more complex and needs, like testing against some type of password history in ActiveDirectory.

Sorry, comments for this entry are closed at this time.