my dog learned polymorphism*
The moose likes Struts and the fly likes Ajax and ActionClass Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "Ajax and ActionClass" Watch "Ajax and ActionClass" New topic
Author

Ajax and ActionClass

Raminder Singh
Ranch Hand

Joined: Mar 01, 2002
Posts: 72
Hi,

i have some doubt reg. Ajax in Struts.

Let say we make URL from java script n call a method in action class:

var url = "/PackageRates.do?countryCode=" + escape(code);
var req = initRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
//parseMessages(req.responseXML);
//alert("URL Exists!");
alert("responseText: " + req.responseText);
} else if (req.status == 404){
alert("URL doesn't exist!");
} else
{
alert("Status is "+req.status)
}
}
};

i have doubt here....
In PackageRatesAction Class(PackageRates.do refer this)...

if we have a method
public ActionForward getCityList(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
{

String countryCode = request.getParameter("countryCode");
...n get list of cities.

......
......

return mapping.findForward("some fwd");
}

now how to
1) get back this list as response??

2) do we need to set list in response Object..n set ActionForward to same JSP??

its very urgent.


thanks
raminder.s
Vani Bandargal
Ranch Hand

Joined: Oct 06, 2005
Posts: 82
1. You have to return null from your action class method
ex: return mapping.findForward(null);

2. You have to build response object like this:
I am giving my code as an example. Here I am builiding second
dropdown based on value selected in first deopdown.

response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
out.flush();
out.println("<table cellpadding=\"3\" width=\"99%\" border=\"1\" bordercolor=\"#5678BC\"> ");
out.println("<tr class=\"tr3\"> ");

out.println("<td class=\"td1\">Select test to map to supplemental form:" );
out.println("<select name=\"hepTest_" + selectedObrIdentifier + "\" size=\"1\" styleClass=\"RegSelect\"> ");
out.println("<option value=\"\">Please Pick One </option>");

/* other values go here by calling DAO objects
out.println("</select>");
out.println("</td>");

in mu jsp I have a span tag.
I do something like this
function processStateChange() {
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
document.getElementById("span_" + selectedObrIdentifier).innerHTML= req.responseText;
} else {
alert("Problem with server response:\n " + req.statusText);
}
}
}

I also had some problem using AJAX in Struts. I found solution today only and it is working now.
Let me know if this helps
murali kankanala
Ranch Hand

Joined: Nov 15, 2004
Posts: 110
Hi Vani,


If i written the XML stuff into response.getWriter().write("XML stuff");

Do you know how to read that in JavaScript , when i tried with

request.responseXML it is giving null.

If u know give reply soon it will be helpful to me.
Vani Bandargal
Ranch Hand

Joined: Oct 06, 2005
Posts: 82
Murali,
I have not tried request.responseXML. Initially when I tried responseXML, I was getting null, I did not do much R & D on this.

I started using request.resposeText and it worked.

request.resposeText will have the contents that I put in my action class.
But make sure that you use flush method otherwise it will have all the generated HTML code. do like this
response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
out.flush();

after this line you put whatever you want in PrintWriter out.

My sample code is like this:
out.println("<table cellpadding=\"3\" width=\"99%\" border=\"1\" bordercolor=\"#5678BC\"> ");
out.println("<tr class=\"tr3\"> ");

out.println("<td class=\"td1\">Select test to map to supplemental form:" );
out.println("<select name=\"hepTest_" + selectedObrIdentifier + "\" size=\"1\" styleClass=\"RegSelect\"> ");
out.println("<option value=\"\">Please Pick One </option>");
out.println("</select>");
out.println("</td>");
out.println("</tr>");
out.println("</table>");

Make sure you return null from your action class method like this
return mapping.findForward(null);

in my Jsp I have a span tag. All I do finally is wirite to innerHTML of that tag like this:
if (req.status == 200) { // OK response
document.getElementById("span_" + selectedObrIdentifier).innerHTML= req.responseText;
}

this gives me my second dropdown.
Raminder Singh
Ranch Hand

Joined: Mar 01, 2002
Posts: 72
Hi Vani,
Thanks for your support.

But In IE:
showing nthing.

In FireFox:
responseText returning me full htmlCode of my same JSP..without required table tag/data(set in action class).

I'm doing like below now:
JSP:
----
<span id="ajaxText">xx</span>

ActionClass:
------------
String cityListSize = String.valueOf(resultList.size());
response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
out.flush();

out.println("<table>");
out.println("<tr>");
out.println("<td>List Size:</td>");
out.println("<td>" + cityListSize + "</td>");
out.println("</tr></table> ");

//return null;
return mapping.findForward(null);

and

if (req.status == 200) {
//parseMessages(req.responseXML);
//alert("URL Exists!");
alert("responseText: " + req.responseText);
document.getElementById("ajaxText").innerHTML= req.responseText;
-----------------------------------------------------------------
murali kankanala
Ranch Hand

Joined: Nov 15, 2004
Posts: 110
Hi Vani,

Thanks for great response.

As u said it is right.

But according to my requirement i want to set one message in action class.

And i want to read that message in JavaScript , depending on that message

value i want to popup a dialog box to show that message.

If we can do this thing by using request.responseText , then u can tell me

how to set that value in html and how to read that in javascript by using

request.responseText object.
Vani Bandargal
Ranch Hand

Joined: Oct 06, 2005
Posts: 82
Murali,
Let's say you have a control by name "showMessages" in your jsp like this

<html:hidden property="showMessages" />
Make sure that you have getter and settter methods

now in Action class method that you are calling from Ajax, you can do some thing like this
response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
out.flush();
out.println("true");
return mapping.findForward(null);

in your jsp:

function replyMethod()
{
if(request.readyState == 4)
{
if(request.status == 200)
{
document.getElementById("showMessages").value=req.responseText;
}
}
if(document.getElementById("showMessages").value =='true')
{
alert("your alert message");
}
}
Vani Bandargal
Ranch Hand

Joined: Oct 06, 2005
Posts: 82
Raminder
I tried your code. I get List Size: 10 in placse of XX (Span tag) after Ajax call.
Raminder Singh
Ranch Hand

Joined: Mar 01, 2002
Posts: 72
Hi Vani,
But i'm still getting null.

Don't know whats problem at my side??
can u send me ur syntex..may be smth wrong..i will figure out.


thanks
Durgaprasad Guduguntla
Ranch Hand

Joined: Oct 20, 2003
Posts: 99
Hi,

Once the ajax response is available you can write either a java script alert or HTML. I would prefer returning XML response instead of HTML from action call, so that we can present it in any form in JSP. Please take a look at the following code samples which worked on IE. You will have a drop down of countries to choose from and the ajax call would return cities list as java script alert as well updates HTML DOM.

citieslist.jsp


struts-config.xml


ListCitiesAction.java


ajax.js


Hope this helps.


Thanks,<br />Durgaprasad<br />SCJP1.4, SCWCD1.4, SCBCD1.3,<br />SCEA
murali kankanala
Ranch Hand

Joined: Nov 15, 2004
Posts: 110
Hi Durga Prasad,

You have provided neat code.

But you have not provide code for

DocumentBuilderFactory.java
DocumentBuilder.java
Document.java
Element.java
TransformerFactory.java
Transformer.java
DOMSource.java
StreamResult.java

I come to know that the above classes are doing XML parsing , but we must have that code also to execute your to be worked properly i think.

So please send code snippet for the above classes also.

Waiting for your code snippets.
murali kankanala
Ranch Hand

Joined: Nov 15, 2004
Posts: 110
Hi Durga Prasad,

I got the solution , no probs , it is working fine. Thank you very much.

Hi Vani and Raminder Singh , i observed one thing that if you try to
print the request.responseXML it won't give any thing but gives NULL,
but if you want to see the XML content that you returned from Action class use request.responseText.

And dont confuse if the request.responseXML is null how to use the
var rootEle = request.responseXML.getElementsByTagName("cities")[0];
but this works fine.

Please dont stuck-up why request.responseXML giving NULL. Just leave it.
continue with next steps. i.e.
var rootEle = request.responseXML.getElementsByTagName("cities")[0];
you won't get any problem.

Prasad has not provided the code snippets for the classes

DocumentBuilderFactory.java
DocumentBuilder.java
Document.java
Element.java
TransformerFactory.java
Transformer.java
DOMSource.java
StreamResult.java

so you hard code your won XML content there, since you are not having the
above generalized classes to produce the XML content.

Action class

public ActionForward perform(.......)
{
// i am sending some name from JSP, so i am reading that value here
String name = request.getParameter("name");
response.setContentType("text/xml; charset=UTF-8");
response.setHeader("Cache-Control","no-cache");

StringBuffer buffer = new StringBuffer();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<root>");
buffer.append("<messageValue>");

String message = "";
if(name != null && name.equalsIgnoreCase("myname")
{ message="Valid";
}else
{ message="InValid";
}
buffer.append("<value>"+message+"</value>");
buffer.append("</messageValue>");
buffer.append("</root>");

response.getWriter().flush();
response.getWriter().write(buffer.toString());

return mapping.findForward(null);
}//perform()
Durgaprasad Guduguntla
Ranch Hand

Joined: Oct 20, 2003
Posts: 99
Hi Murali,

All the standard classes I have used to generate DOM are part of JAXP which is included in J2SDK1.4. They are readily available for you if you are using J2SDK1.4. You can see the following imports in the action class for your reference:
murali kankanala
Ranch Hand

Joined: Nov 15, 2004
Posts: 110
Hi Durga Prasad,

Thanks for the reply and i having some doubts

1) If the DataBase is taking lot of time to produce the results in Action class (depending on those results only i want to set the values into XML) then, automatically the AJAX response also will have to wait upto until the DataBase results comes.

Although using AJAX the user have to wait upto DataBase results comes to Action class

Is the AJAX right one to use in this case ?
Is the AJAX having solution for this ?

2) Can we set the Attributes into HttpServletRequest in Action , and reading those in JSP.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Ajax and ActionClass
 
Similar Threads
Doubt
pass <bean:write> to a function
Action class being called only once in ajax
AJAX Call timout: code: 12002
populate <html:options> with AJAX response