This week's book giveaway is in the Agile and Other Processes forum. We're giving away four copies of Darcy DeClute's Scrum Master Certification Guide: The Definitive Resource for Passing the CSM and PSM Exams and have Darcy DeClute on-line! See this thread for details.
Struts was made for the traditional "display a page, submit a form" style of web application, and as such doesn't really fit well with AJAX. I've found that for some tasks, an AJAX approach works better, and for others, the traditional approach works better. There are other frameworks that were built specifically for AJAX, such as The AJAX tag library and DWR.
I believe the best approach is to use Struts when a traditional approach is called for and another framework when AJAX is called for. This link talks about how to integrate DWR and Struts.
If you want to take control of what the Action class returns, just use the HTTPServletRequest object's PrintWriter, and format the response however you want. You'll then return null from the execute() method to tell Struts you've taken care of the response yourself, and not to forward to any other JSP.
I am curious if others have successfully integrated Ajax into their Struts applications. It does not seem that difficult, but I could see where some trial and error would have to occur to develop some best practices.
It seems like DispatchAction might be a good approach so that you do not have to create a new Action class for every piece of data that you want to retrieve. I could see where some of the wildcard features could help with creating Action Mapping entries (is that 1.2 or 1.3?). What issues have other hit? Did you find that you had to duplicate code (once in your main action and once in the ajax action)?
Here's a few more details about my experience with AJAX.
Right from the start, I could see that Action classes just weren't a very good fit for AJAX. There's a lot of unnecessary stuff in them that AJAX doesn't need to worry about. Also, the whole idea of returning an ActionForward doesn't fit at all, since AJAX returns an XML response, rather than a JSP. This left me finding ways around the Struts framework, such as returning a null ActionForward and finding my own way to return a response. When I find myself doing work to get around a framework, that's a sign that it doesn't fit, and sends me searching for something else.
I then created some wrappers for these Business Delegates. These wrappers just verify that the users are valid, logged-on users, and they have authority to do what they're trying to do and then passes the call on to the Business Delegate. I now call the wrappers from AJAX, and that seems to solve the security problem.
I find that this mix of Struts and DWR works pretty well. Both Struts and DWR call some of the same Business Delegate classes, so there's really not much duplication of code. Security checking is about the only area where code is duplicated, but later I may re-factor some of my security checking code into common classes that can be called by either Struts or DWR.
I still firmly believe that most web application problems are best solved by the traditional "display a page, read a form" approach, and of course Struts works great for those pages. There are a few problems that AJAX handles much better, and for those tasks, I use AJAX and DWR.
I have never tried using the responseText property. I've always used responseXML.
One important thing to check is that in your action, you must code: response.setContentType("text/xml");
The best way to do it is like this:
var elements request.responseXML.getElementsByTagName('myTag');
the variable elements is now an array containing all the elements in the XML with <myTag>. If it's just a simple tag with String content, you get the value with .childNodes.nodeValue. If an element has child elements, you can again use getElementsByTagName() to drill down and get those child elements.
Here's the rule the XMLHttpRequest object is supposed to follow:
It will first try to parse the data returned from the server into an XML DOM. If it succeeds, the responseXML property will contain the DOM for the returned XML. If it fails, the responseText property will contain the text returned. Therefore, if the XML you create is malformed in any way, the responseText property will be populated instead of the responseXML property. As to why the XMLHttpRequest object wasn't able to parse your XML, I'm afraid I don't know.