Thursday, June 25, 2009

JSON, DOJO and innerHtml and Java Handler.

JSON : JavaScript Object Notation, it is the data interchange format, It simplify the data exchange between client side to server side script. In the example we will pass two string and return a Java MAP response.

DOJO : Is the working dog for ajax communication.

innerHtml: this is useful to replace a element in the html document to be replaced with a ajax response. call the element by dojo.byId("someid") then replace the content of the id by innerHtml. The id can be given to any html element.

Our Architecture
Format data to JSON content---> Dojo ---------> xhrPost.Post --> Java Handler process-------> send back JSON response to DOJO------> DOJO display on html.
Our Javascript
//Ajax call to return a list of attributes function processBalanceAjaxLookup( CardNo,pinNo, callbackfunction){ var ajaxCommand = {}; ajaxCommand.command="BalanceLookup"; ajaxCommand.formData={"CardNo":CardNo,"pinNo":pinNo}; ajaxCommand.requestURI="/"; var bindArgs = { url: "/ajax", handleAs: "json-comment-filtered", content: {ajaxCommandData: [JSON.stringify(ajaxCommand)]}, error: function(type, errObj){ }, load: function(type, data){ callbackfunction(type); } }; var requestObj = dojo.xhrPost(bindArgs); } //function to be called by the jsp function checkBalance() { var CardNo = document.getElementById("Number").value; var pinNo=document.getElementById("Pin").value; processBalanceAjaxLookup(No,pinNo,processBalanceAjaxLookupCallback); } //call back function or the response function function processBalanceAjaxLookupCallback(attributeData){ //response token var tokens = dojo.objectToQuery(attributeData).split("&") //inner html tags that have to be replaced. var errorTag=dojo.byId("gcError"); var balanceTag = dojo.byId("gcBalance"); var dateTag=dojo.byId("gcDate"); var cardNoTag=dojo.byId("gcNo"); for(var i = 0; i < tokens.length;i++){ var responseData = tokens[i].split("="); if(responseData[0] == "validity"){ if (responseData[1]== "valid" ){ }else{ balanceTag.innerHTML=""; dateTag.innerHTML=""; errorTag.innerHTML="Invalid Card"; } } else if(responseData[0] == "balance") { balanceTag.innerHTML=responseData[1]; } else if(responseData[0] == "date") { var nowdate = new Date(); //alert (nowdate); dateTag.innerHTML= nowdate ; } else if(responseData[0] == "CardNo") { cardNoTag.innerHTML=responseData[1]; } else if(dojo.byId(responseData[0])) errorTag.innerHTML = responseData[1]; } }
The Html code which calls the function
< a href="#getBalance" class="nyroModal" onClick= javascript: checkBalance()>< img src="images/checkBalance-Btn.gif" width="140" height="41" />
The Java Code
public JSONObject process(HttpServletRequest request, WebApplicationContext factory, JSONObject ajaxData) throws JSONException { JSONObject rval = null; try { String balance= new String("199393.00"); //process the info and return Map responseMap = new HashMap (); if ( CardNo != null ){ responseMap.put("validity", "valid"); responseMap.put( "CardNo", maskGc(CardNo)); responseMap.put("date", formatDate); responseMap.put("balance", balance); rval= new JSONObject(responseMap); }else{ responseMap.put("validity", "invalid"); responseMap.put( "CardNo", ""); responseMap.put("date", ""); responseMap.put("balance", ""); rval= new JSONObject(responseMap); } } catch (Exception e) { e.printStackTrace(); throw new JSONException("Error retrieving Card Balance."); } return rval; }
An Abstract class to invoke the Spring handler and process AJAX calls
public class AbstractAjaxServlet extends HttpServlet { private static Logger myLogger = Logger.getLogger(AbstractAjaxServlet.class); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doProcess(req, resp); } catch (IOException e) { e.printStackTrace(); throw e; } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doProcess(req, resp); } catch (IOException e) { e.printStackTrace(); throw e; } } /** * Parses an incoming ajax command object and uses the command name to perform * a Spring lookup for an appropriate handler. Returns the handler's return value * as JSON back to the caller. * * @param req * @param res * @throws IOException */ private void doProcess(HttpServletRequest req, HttpServletResponse res) throws IOException { myLogger.info("> doProcess", null); res.setContentType("text/json-comment-filtered"); if (req.getParameterValues("ajaxCommandData") == null) { return; // We don't know how to handle the request. } String json = req.getParameterValues("ajaxCommandData")[0]; try { JSONObject jsonObject = new JSONObject(json); // Delegation time. String command = jsonObject.getString("command"); // Take the command string and lookup a Spring object to handle it. String handlerName = command; handlerName = handlerName.substring(0, 1).toUpperCase() + handlerName.substring(1); handlerName = "AjaxHandler" + handlerName; WebApplicationContext factory = WebApplicationContextUtils.getWebApplicationContext(req.getSession().getServletContext()); if (!factory.containsBean(handlerName)) { throw new IOException("Invalid ajax handler " + handlerName); } AbstractAjaxHandler handler = (AbstractAjaxHandler) factory.getBean(handlerName); JSONObject returnValue = handler.process(req,factory,jsonObject); res.getWriter().println("/* " + returnValue + " */"); } catch (JSONException e) { e.printStackTrace(); throw new IOException(e.toString()); } myLogger.info("< doProcess", null); } }

Masking for Credit Cards

This will show only the last 4 digits .

private String maskGc(String oS){ int beginIndex=0; int endIndex=12; if (oS.length()>15){ oS= oS.replace(oS.substring(beginIndex, endIndex), "****************"); return oS; } Output: ****************3456

Tuesday, June 2, 2009

Solr/Lucene .

I am trying to add up what I learned so far on the Solr.

Lucene : Is the search engine

Solr : The Search Server.

Solr / Lucene Terms.

Facet --- The data that have to be breakdown. example: manufacturer
FacetField -- This will contain the facet data
SolrDocument -- This will contain one solr search data.
setFacetMinCount -- This will limit returning search data with the minimum count of hit.
A sample Query using SolrJ
query.addFacetField("manu"); query.setFacetMinCount(1); query.setIncludeScore(true); List facetFieldList=qr.getFacetFields(); for(FacetField facetField: facetFieldList){ System.out.println(facetField.toString() +"Manufactures"); } And it returns ----------------- [manu:[dell (5), inc (5), corp (1), sharp (1), sonic (1), view (1), viewson (1), vizo (1)]] Notice here it will return only manufactures with facet count 1 and above.
Solr Price Range:
Querying price range need little special skill in solr, I am still exploring different option of querying. The search querys are case sensitive, if you put 'To' instead of 'TO' solr will throw invalid syntax error.
query.addFacetQuery("price:[* TO 500]"); query.addFacetQuery("price:[500 TO 1000]"); query.addFacetQuery("price:[1000 TO *]"); HashMap priceRangeMap = (HashMap) qr.getFacetQuery(); Iterator priceRageIter=priceRangeMap.entrySet().iterator(); System.out.println(qr.getFacetQuery().toString()); while(priceRageIter.hasNext()){ Map.Entry pairs = (Map.Entry)priceRageIter.next(); System.out.println(pairs.getKey() + " -- found -- " + pairs.getValue()); } And it will return ---------------------- {price:[* TO 500]=1, price:[500 TO 1000]=2, price:[1000 TO *]=6} price:[* TO 500] -- found -- 1 price:[500 TO 1000] -- found -- 2 price:[1000 TO *] -- found -- 6