My Blogs

Monday, March 12, 2007

DWR-2.0.rc2 + Spring 2.0 integration

Steps to integrate DWR with Spring 2.0 using new Name Spaces that were introduced. The integration currently works with Spring 2.0 and DWR-2.0RC-2 versions only. This does not work with Spring 2.0.1 or 2.0.2 or 2.0.3 and DWR-2.0RC-2, in order to work with spring 2.0+ versions you need get the current version of DWR-2.0RC-2 from HEAD of the CVS.

Step 1: Download 2.0 version of Spring form http://www.springframework.org/
Step 2: Download DWR version 2.0-rc2 from http://getahead.org/dwr/download

Copy spring and dwr jar files to the webapplication classpath.

Step 3: Add the below lines into web.xml

<servlet>

<servlet-name>dwr-spring</servlet-name>

<servlet-class>

org.springframework.web.servlet.DispatcherServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>dwr-spring</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>dwr-spring</servlet-name>

<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

<welcome-file-list>

<!-- index page -->

<welcome-file>index.jsp</welcome-file>

<welcome-file>index.html</welcome-file>

</welcome-file-list>


Step 4: Create the default Spring MVC context file dwr-spring-servlet.xml under WEB-INF directory of the webapplication and configure the DWR

<?xml version="1.0"
encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

http://www.directwebremoting.org/schema/spring-dwr

http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">


<!-- DWR CONFIGURATION -->

<dwr:configuration>

<dwr:create
javascript="JDate" type="new"

class="java.util.Date" />
</dwr:configuration>




<dwr:controller id="dwrController" debug="true" />

<bean id="dwrHandlerMappings"

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="alwaysUseFullPath"
value="true" />

<property
name="mappings">

<props>

<prop key="/dwr/**/*">dwrController</prop>

</props>

</property>

</bean>

<!-- END OF DWR CONFIGURATION -->

</beans>

Step 5: Deploy the application in Tomcat 5.5 and point the browser to http://localhost:8080/dwr-spring/dwr/index.html

If the integartion is sucessfull it should display the page with JDate link on the page.

Blow links provides more information on how to integrate DWR and Srping

http://bram.jteam.nl/index.php/2007/01/

Saturday, January 06, 2007

Tomcat 5.5 with JDK 1.4

To setup tomcat 5.5 or grater version on JDK 1.4 you need to download JDK 1.4 Compatability Package along with windows installer form http://tomcat.apache.org/. When installing the tomcat 5.5 it will by default look for JDK 5 ver, but it will still install the tomcat but when you run the tomcat it will display a message "This release of Apache Tomcat was packaged to run on J2SE 5.0 or later". To make it run under jdk 1.4 unzip the JDK 1.4 Compatability Package and copy the .jar file bin directory to the TOMCAT_HOME\bin directory and copy the .jar files under the common\endorsed to the TOMCAT_HOME\common directory. Now you should be able to run the tomcat by type in the http://localhost:8080/ in your favorite browser.

Tuesday, February 21, 2006

Ajax + JSP to populate dependent dropdown

This example refers to the same as Startups + Ajax by example but here I am using JPG instead of Struts. The example has only dependency to prototype.js and is more helpful if you are using just JSP. You can download the latest code of prototype.js Prototype is wonderful to have in your toolkit as it makes life easy for a JSP or JavaScript developer.

The example is about how to populate the dependent dropdown list without refreshing the entire page when one of the options is selected. The example uses 2 jsp pages, first jsp (ajaxOptions.jsp) and uses prototype.js file and which has AJAX calls to the second jsp(ajaxOptionResult.jsp) this jsp returns XML as a response.

1. ajaxOptions.jsp
Make sure you have the prototype.js file as a part of you web application and reference the path in this jsp page in my case I have the js file under js/ajax/

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>Address Form</title>
<!-- include the AJAX JS File -->
<script src="js/ajax/prototype.js" type="text/javascript"></script>
<SCRIPT LANGUAGE="JavaScript">

/*
onChange event of the dropDownList will calls this function
which has AJAX call to Struts Action class
@param: dropDownList object (this)
@param: URL or Struts Action
*/
function depedentDropDown(obj, url) {
var stateValue = $F(obj)
var pars = "state=" + stateValue;
//alert(stateValue);
var myAjax = new Ajax.Request(url, {method: 'get', parameters: pars,
onComplete: showResponse});
}

/*
Upon completing the request the AJAX will call this method
which is responsible for loading the depedent list from the XML
*/
function showResponse(originalRequest)
{
var list = $('city');
var xmlString = originalRequest.responseXML;
var items = xmlString.getElementsByTagName('labelValueBean');
clearList(list);
if (items.length > 0)
{
for (var i = 0; i < items.length; i++)
{
var node = items[i];
var value = "";
var label = "";
if (node.getElementsByTagName("label")[0].firstChild.nodeValue) {
value = node.getElementsByTagName("label")[0].firstChild.nodeValue;
label = node.getElementsByTagName("value")[0].firstChild.nodeValue;
}
addElementToList(list, value, label);
}
}
else
{
addElementToList(list, "", "-- Select is Empty --");
}
}

/**
remove the content of te list
*/
function clearList(list)
{
while (list.length > 0)
{
list.remove(0);
}
}

/**
Add a new element to a selection list
*/
function addElementToList(list, value, label)
{
var option = document.createElement("option");
option.value = value;
var labelNode = document.createTextNode(label);
option.appendChild(labelNode);
list.appendChild(option);
}



</SCRIPT>
</head>
<body>
<form method="POST" action="">
<fieldset style="padding: 2">
<legend>Address Form</legend>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="58%">
<tr>
<td width="24%">Address</td>
<td width="76%">
<input type="text" name="address1" size="20"/>
</td>
</tr>
<tr>
<td width="24%">Apt#</td>
<td width="76%">
<input type="text" name="address2" size="20"/>
</td>
</tr>
<tr>
<td width="24%">State</td>
<td width="76%">
<select size="1" name="state" onChange="depedentDropDown(this,'ajaxOptionResult.jsp')">
<option>Select State</option>
<option value="VA">VA</option>
<option value="MD">MD</option>
</select>
</td>
</tr>
<tr>
<td width="24%">City</td>
<td width="76%">
<select size="1" name="city">
<option>Select City</option>
</select>
</td>
</tr>
<tr>
<td width="24%">Zip</td>
<td width="76%">
<input type="text" name="zip" size="20"/>
</td>
</tr>
</table>
</fieldset>
<p>
<input type="submit" value="Submit" name="B1"/>
<input type="reset" value="Reset" name="B2"/>
</p>
</form>
</body>
</html>

2. ajaxOptionResult.jsp this JSP page response is of type "text/xml"

<%

String state = request.getParameter("state");
String[] vaArray = new String[]{"Reston", "Centerville", "Chantilly", "Fairfax"};
String[] mdArray = new String[]{"Silver Spring", "Rockwill", "Bethesda", "Brandywine" };
// pouplate the state
StringBuffer buffer = new StringBuffer();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("\n");
buffer.append("<root>");
buffer.append("\n");
if(state.equals("VA")){
for(int i=0; i < vaArray.length; i++){
buffer.append("<labelValueBean>");
buffer.append("\n");
buffer.append("<label>" + vaArray[i] + "</label>");
buffer.append("\n");
buffer.append("<value>"+ vaArray[i]+"</value>");
buffer.append("\n");
buffer.append("</labelValueBean>");
}
}else if(state.equals("MD")){
for(int i=0; i < mdArray.length; i++){
buffer.append("<labelValueBean>");
buffer.append("\n");
buffer.append("<label>" + mdArray[i] + "</label>");
buffer.append("\n");
buffer.append("<value>"+ mdArray[i]+"</value>");
buffer.append("\n");
buffer.append("</labelValueBean>");
}
}else{
buffer.append("<labelValueBean>");
buffer.append("\n");
buffer.append("<label>Selet is empty</label>");
buffer.append("\n");
buffer.append("<value>Empty</value>");
buffer.append("\n");
buffer.append("</labelValueBean>");
}
buffer.append("\n");
buffer.append("</root>");
System.out.print(buffer.toString());
response.addHeader("Content-Type", "text/xml");
response.setContentType("text/xml; charset=windows-1252");
out.write(buffer.toString());
%>

It is as simple as it is.

Wednesday, January 18, 2006


Venu Reddy Posted by Picasa

Struts and AJAX by example - 1

In the resent times I have been reading some interesting articles about AJAX and wanted to some examples using struts with AJAX.

1. Dependent Select Boxes
2. Suggest Text Field

The examples above assume that the user have a fair understanding about XMLHttpRequest and JavaScript. In the examples I will be using prototype.js Javascript Framework and script web 2.0 javascript.

prototype.js has all the utility functions to make an XMLHttpRequest to server and srcipt.aculo.us as the utility methods for effects and suggest layer generation and much more if you want to use.

Dependent Select Box:

Let‘s take a classic example of Address Form in a JSP page. Upon selecting the State from the Dropdown List corresponding City‘s needs to be populated in the city dropdown list. The question still remains why should I use AJAX? Well, the advantage of using AJAX is it will not reloaded or refreshed the complete page it will reload just the dependent dropdown list with values that are comming from the server.

addressForm.jsp is a simple JSP page which has a HTML Form and Form elements. In the JSP documentation for porototype
The AJAX request here is expecting an XML file with a list of LabelValueBean objects.
page I have included prototype.js file as script include. Here is the JSP page looks like

<code>

<html>



<head>

<title>Address Form</title>

<!-- include the AJAX JS File -->

<script src="js/ajax/prototype.js" type="text/javascript"></script>

<SCRIPT LANGUAGE="JavaScript">

<!--

/*

onChange event of the dropDownList will calls this function

which has AJAX call to Struts Action class

@param: dropDownList object (this)

@param: URL or Struts Action

*/

function depedentDropDown(obj, url){

var stateValue = $F(obj)

var pars = "state=" + stateValue;

var myAjax = new Ajax.Request( url, {method: 'get', parameters: pars,
onComplete: showResponse});

}



/*

Upon completing the request the AJAX will call this method

which is responsible for loading the depedent list from the XML

*/



function showResponse(originalRequest)

{

var list = document.getElementById('city');

var xmlString = originalRequest.responseXML;

var items = xmlString.getElementsByTagName('labelValueBean');

clearList(list);

if (items.length > 0)

{

for (var i=0; i<items.length; i++)

{

var node = items[i];

var value="";

var label="";

if(node.getElementsByTagName("label")[0].firstChild.nodeValue){

value = node.getElementsByTagName("label")[0].firstChild.nodeValue;

label = node.getElementsByTagName("value")[0].firstChild.nodeValue;

}

addElementToList(list, value, label);

}

}

else

{

addElementToList(list, "", "-- Select is Empty --");

}

}



/**

remove the content of te list

*/

function clearList(list)

{

while (list.length > 0)

{

list.remove(0);

}

}



/**

Add a new element to a selection list

*/

function addElementToList(list, value, label)

{

var option = document.createElement("option");

option.value = value;

var labelNode = document.createTextNode(label);

option.appendChild(labelNode );

list.appendChild(option);

}



//-->

</SCRIPT>

</head>



<body>



<form method="POST" action="">



<fieldset style="padding: 2">

<legend>Address Form</legend>

<table border="0" cellpadding="0" cellspacing="0" style="border-collapse:
collapse" bordercolor="#111111" width="58%">

<tr>

<td width="24%">Address</td>

<td width="76%"><input type="text" name="address1" size="20"></td>

</tr>

<tr>

<td width="24%">Apt#</td>

<td width="76%"><input type="text" name="address2" size="20"></td>

</tr>

<tr>

<td width="24%">State</td>

<td width="76%"><select size="1" name="state" onChange="depedentDropDown(this,'ajaxOptionList.do')">

<option>Select State</option>

<option value="VA">VA</option>

<option value="MD">MD</option>

</select></td>

</tr>

<tr>

<td width="24%">City</td>

<td width="76%"><select size="1" name="city">

<option>Select City</option>

</select></td>

</tr>

<tr>

<td width="24%">Zip</td>

<td width="76%"><input type="text" name="zip" size="20"></td>

</tr>

</table>

</fieldset>



<p><input type="submit" value="Submit" name="B1"><input type="reset"
value="Reset" name="B2"></p>

</form>



</body>



</html>

</code>




Struts Action Classes:

To make the process little convenient and reusable I created an abstract class which extends Action which has an abstract method which can be implemented by extending subclasses. The super class is responsible for generating the XML and sending the request back. For turning Java Object into XML I have used Commons Betwixt an open source for Jakarta. Download the jar file and included it in the classpath. i.e., copy the betwixt.jar file into WEB-INF/lib folder of the application. (Note: If you are not using struts then betwixt has dependencies all the jar files needs to be in the classpath )

AjaxOptionsAction.java

import java.beans.IntrospectionException;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.betwixt.strategy.DecapitalizeNameMapper;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.xml.sax.SAXException;

public abstract class AjaxOptionsAction extends Action {
/**

  • This is the main action called from the Struts framework.
  • @param mapping The ActionMapping used to select this instance.
  • @param form The optional ActionForm bean for this request.
  • @param request The HTTP Request we are processing.
  • @param response The HTTP Response we are processing.
  • @return
  • @throws javax.servlet.ServletException
  • @throws java.io.IOException

*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
String buffer = getXMLObject(request);
response.addHeader("Content-Type", "text/xml");
response.setContentType("text/xml; charset=windows-1252");
response.getOutputStream().print(buffer.toString());
return null;
}

/**

  • Get's the List object from the extended class and convets the List to XML

*

  • @param request
  • @return

*/
public String getXMLObject(HttpServletRequest request) {
List list = getDropDownList(request);
String xmlString = toXML(list, "root");
return xmlString;
}

/**

  • This will convert the Object into XML

*

  • @param root
  • @param object
  • @return

*/

public String toXML(Object object, String root) {
StringWriter outputWriter = new StringWriter();
// Betwixt just writes out the bean as a fragment
// So if we want well-formed xml, we need to add the prolog
outputWriter.write("");
outputWriter.write("\n");
// Create a BeanWriter which writes to our prepared stream
BeanWriter beanWriter = new BeanWriter(outputWriter);
beanWriter.getBindingConfiguration().setMapIDs(false);
beanWriter.getXMLIntrospector().getConfiguration().setElementNameMapper(new DecapitalizeNameMapper());
beanWriter.enablePrettyPrint();
try {
beanWriter.write(root, object);
} catch (IOException e) {
System.out.println(e.toString());
} catch (SAXException e) {
System.out.println(e.toString());
} catch (IntrospectionException e) {
System.out.println(e.toString());
}

beanWriter.setIndent(outputWriter.toString());
return new String(outputWriter.toString());
}

/**

  • The class which extends this calls have to override this method and return a List Object

*

  • @param request
  • @return

*/
public abstract List getDropDownList(HttpServletRequest request);
}

AjaxOptionListAction.java extends AjaxOptionsAction.java and override the method getDropDownList. In the struts-config.xml the mapping would point to this class.

AjaxOptionListAction.java

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.util.LabelValueBean;

public class AjaxOptionListAction extends AjaxOptionsAction
{

public List getDropDownList(HttpServletRequest request)
{

String state = request.getParameter("state");
List list = new ArrayList();
// get the List for DB or form the session which ever is convinent
list = getList(state);
return list;
}

/*
This method is for example only

*/
public List getList(String state) {
List list = new ArrayList();
if (state.equalsIgnoreCase("VA")) {
list.add(new LabelValueBean("Reston", "Reston"));
list.add(new LabelValueBean("Chantilly", "Chantilly"));
list.add(new LabelValueBean("Centreville", "Centreville"));
list.add(new LabelValueBean("Herndon", "Herndon"));
list.add(new LabelValueBean("Eledn st", "Eledn st"));
} else if (state.equalsIgnoreCase("MD")) {
list.add(new LabelValueBean("Silver Spring", "Silver Spring"));
list.add(new LabelValueBean("Rockwill", "Rockwill"));
list.add(new LabelValueBean("BETHESDA", "BETHESDA"));
list.add(new LabelValueBean("BOYDS", "BOYDS"));
list.add(new LabelValueBean("BRANDYWINE", "BRANDYWINE"));
}

return list;
}

}

In struts-config.xml the mapping

<code>

<action path="/ajaxOptionList" type="AjaxOptionListAction"/>

</code>



That is it as simple as it is. In the next phase I will use the same example to populate the Suggest City Text Field insted of city dropdown list.

The above code works fine but if the list is too big then it takes some time to clear the list. We can modify the JavaScript in the jsp page to do much better job.