Problem
Check the availability of ‘Username’ during registration in J2EE web application using Struts 2 and Ajax.
Solution
1. Create the following JavaScript functions for Ajax implementation:
function GetXmlHttpObject() { var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } function AJAXInteraction(url, callback) { var xmlHttp = GetXmlHttpObject(); if (xmlHttp==null) { alert ("Your browser does not support AJAX!"); return; } xmlHttp.onreadystatechange = processRequest; function processRequest () { // readyState of 4 signifies request is complete if (xmlHttp.readyState == 4) { // status of 200 signifies sucessful HTTP call if (xmlHttp.status == 200) { if (callback) callback(xmlHttp.responseXML); } } } this.doGet = function() { xmlHttp.open("GET", url, true); xmlHttp.send(null); } } function validateCallback(responseXML) { var msg = responseXML.getElementsByTagName("valid")[0].firstChild.nodeValue; if (msg == "false") { var mdiv = document.getElementById("userIdMessage"); // set the style on the div to invalid document.getElementById("showErrLabel").style.display="block"; document.getElementById("showErr").style.display="block"; mdiv.className = "contentformlabel_error"; mdiv.innerHTML = "Username already exists."; } else if(msg == "true") { var mdiv = document.getElementById("userIdMessage"); // set the style on the div to valid document.getElementById("showErrLabel").style.display="none"; document.getElementById("showErr").style.display="none"; mdiv.className = "contentformlabel"; mdiv.innerHTML = "Username available"; } else { var mdiv = document.getElementById("userIdMessage"); // set the style on the div to valid document.getElementById("showErrLabel").style.display="block"; document.getElementById("showErr").style.display="block"; mdiv.className = "contentformlabel_error"; mdiv.innerHTML = "Please enter a username"; } }
2. Create another JavaScript function which will be called by the input html element
function validateUserId() { // /marketer/validate.action = namespace/action var url = '<%=request.getContextPath()%>'+"/marketer/validate.action?userId="+document.getElementById("marketer.username_id").value; var ajax = new AJAXInteraction(url, validateCallback); ajax.doGet(); return false; }
3. Create the HTML
<table> <tr> <td class="contentformlabel"> <table cellpadding="0" cellspacing="0" align="right"> <tr> <td style="vertical-align: middle; padding-right: 6px"> <div id="showErrLabel" style="display:none;"> <img src="../images/alert_icon.gif"> </div> </td> <td style="white-space: nowrap"> <font class="contentformlabel_error">*</font> Username: </td> </tr> </table> </td> <td class="contentformfield"> <s:textfield id="marketer.username_id" cssClass="contentforminput-smallhgt" name="marketer.username" size="40" maxlength="25"/> </td> <td colspan="2" style="vertical-align: middle"> <table cellpadding="0" cellspacing="0" align="left"> <tr> <td style="vertical-align: middle; padding-top: 3px; padding-right: 3px"> <input type="image" src="../images/check_availability.gif" onclick="return validateUserId();"> </td> <td style="vertical-align: middle; padding-top: 3px; padding-right: 3px"> <div id="showErr" style="display:none;" align="left"> <img src="../images/left_arrow_red.gif" align="left"> </div> </td> <td style="vertical-align: middle; padding-top: 3px; padding-right: 3px"> <div id="userIdMessage" align="left"></div> </td> </tr> </table> </td> </tr> </table>
4. Create the relevent stylesheets and call it in html
5. Create the Action which will validate the value of “username”
Response object is abstracted in Struts 2 hence will not be able to access it directly from action. So we need to create a custom result object and get the response from it.
package com.util; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.dispatcher.StrutsResultSupport; import com.ajaxproj.action.MarketerAction; import com.ajaxproj.domain.account.Marketer; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; public class ValidateUsername extends StrutsResultSupport { private static final Log log = LogFactory.getLog(ValidateUsername.class); @Override protected void doExecute(String arg0, ActionInvocation arg1) throws Exception { HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(org.apache.struts2.StrutsStatics.HTTP_REQUEST); ActionContext context = arg1.getInvocationContext(); HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE); HttpSession userSession = request.getSession(true); Marketer formMarketer = null; MarketerAction action = ((MarketerAction) arg1.getAction()); formMarketer = action.getMarketerService).checkDuplicateUsername(username); String str = null; PrintWriter out = response.getWriter(); StringBuffer buffer = new StringBuffer(255); // check duplicate username if((username != null) && formMarketer != null) { response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write("<valid>false</valid>"); } else if(username != null && formMarketer == null) { response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write("<valid>true</valid>"); } else { response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write("<valid>Empty</valid>"); } } }
6. Create the default Action
7. Edit Struts.xml (can be struts-<namespace>)
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="marketer" namespace="/marketer" extends="struts-default"> <result-types> <result-type name="validateUserName" class="com.util.ValidateUsername" /> </result-types> <action name="validate" class="com.action.MarketerAction"> <result type="validateUserName">/pages/userregistration/marketerUserInfo.jsp</result> </action> </package> </struts>