wood burning stoves*
The moose likes Struts and the fly likes Struts 1.2.9 +text areas. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "Struts 1.2.9 +text areas." Watch "Struts 1.2.9 +text areas." New topic
Author

Struts 1.2.9 +text areas.

A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
Hi again all .

I am working with a stuts application and I can't for the life of me figure out what is wrong with it. I thought it would be worth clearing up what I understand as the flow control for struts. The part that is confusing me is the (surprise surprise.) textfields and how the reset acts upon them. I got all of my textfields to work, but to keep them working I have to set up the reset so that it provides the same values as the form would before the reset is called. This is being done via a search mode. It seens to me that it is rather difficult ro impossible to put in the values when they are dynamic. Am I mis-understanding how these should be working ? I thought that reset was only called after the first time thuoght.

Just thought that I should note that this is again with indexed text fields.
Brent Sterling
Ranch Hand

Joined: Feb 08, 2006
Posts: 948
I have been programming with Struts for several years and I cannot say for sure that I have ever coded a reset method. The basic reason is that I stick with request scoped forms. The reset method is still called with request scoped forms, but a new instance of the action form is created each time. Are you using session scoped forms?

I know enough about the purpose of the reset method to know that what you are doing should not be needed. The reset method is called once for each action. If you are doing more than just setting values to a default state (the most important being setting boolean values tied to checkboxes to false) then you are probably doing something wrong.

I was going to link you over to the thread "Struts +retrieving values from text area" for more info on lazy loading...but I see it was you that started that thread. It sounds like you don't completely understand indexed properties.

Say you have a collection of User objects on your form stored in the property userList. You read those from the database so userList contains 4 User objects when the page is shown. Each User object has the properties name (getName, setName) and age (getAge, setAge). You iterate over the list when you show the jsp and you see the following (pretend that the age field is a text box):

Bill - 25
Jim - 40
Kelley - 29
Susan - 49

The user edits some values and submits the form. If you form is request scope then a brand new instance of your form is created. The userList property will be what ever it is set to in your constructor (maybe null or maybe an empty ArrayList). To support indexed properties your form also needs an indexed method like getUser(int index). When the form is saved, there will be method calls on your form something like this (btw, I don't know what causes the order of the indexes, but it is generally not in order):

getUser(3).setAge("49");
getUser(1).setAge("40");
getUser(0).setAge("25");
getUser(2).setAge("29");

So how will your getUser method behave when userList is null or an empty list? Will it throw a null pointer exception or an array out of bound error? That is the issue that the example that I posted on the other thread tries to solve. It makes sure userList is not null (you could do that in the constructor as well). It makes sure that when getUser(3) is called and userList is empty, that it adds User objects to the list to prevent the out of bound error. If you just had the last line in there, you would get errors.


Does that make sense?

- Brent
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
You are right in saying that I don't 100 % understand indexed properties, and I'm sure its just one little nugget of information that I am missing and then all of a sudden everything will be clear. (This is unfortunately my usual pattern) I am using request scope, but I think because I don't have proper getter and setter methods I ended up needing the reset() method - (after many iterations of trial and error I got it to work using the reset method but a new page now doesn't give me the option of using the reset method).

I will re-examine my code, as I think I understand what you have all been so patiently trying to get through to me. If I can't get it to work I will post what I have and hopefully one of you fine people can point out where my understanding breaks down.
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
Seems I am still lost so I am going to post what I have and hopefully someone can guide me once again:

Here is what I have (been reworking it so often some of it may have de-evolved sorry about that )

The part I really don't follow is that when there is nothing in the ArrayList then the code works fine, but as soon as there is even 1 element then I am getting a null pointer exception. Any thoughts or suggestions as to what might be causing the NPE ?


thanks for all the help and advice once again:

Here is the relevant Action class info:


public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
SkuSearchForm skuform = (SkuSearchForm) form;
HttpSession session = request.getSession();
SearchDAO sDAO = new SearchDAO();
User user = new User();
Order order = new Order();
ArrayList products = new ArrayList();
ArrayList results = new ArrayList();
user = (User)session.getAttribute("User");
order = user.getOrder(user.getCurrOrder());
products = order.getProducts();

int number = 0;
int count = 0;

while(count < results.size())
{
Product p = (Product) skuform.getResults(count);
count++;

}

return mapping.findForward("success");
}



Here is the relevant JSP page:



<html:form action="/searchResults" method="post" >

<center><p><html:submit>Add To Order</html:submit></p></center>

<table align ="center" width="90%" border=1>
<tr>
<td>Product</td>
<td>Product Desc</td>
<td>Quantity</td>
</tr>

<logic:notEmpty name="SkuSearchForm" property="results">
<logic:iterate name="SkuSearchForm" property="results" id="results">
<tr>

<td><bean:write name="results" property="product" /></td>
<td><bean:write name="results" property="description" /> </td>
<td ><html:text name="results" property="numProducts" indexed="true" /></td>

</tr>
</logic:iterate>
</logic:notEmpty>

<logic:empty name="SkuSearchForm" property="results">
<tr><td colspan="3" align="center">NO RESULTS</td></tr>
</logic:empty>


</table>
</html:form>

And finally here is the relavent form page:
public void setResults(ArrayList results)
{
this.results=results;
}

public ArrayList getResults()
{
return this.results;
}

public Product getResults(int index)
{
if(this.results == null)
{
this.results = new ArrayList();
}
while(index>= this.results.size())
{
this.results.add(new Product());
}

return (Product)results.get(index);
}

public void reset(ActionMapping mapping,HttpServletRequest request)
{
HttpSession session = request.getSession();
results = null;
}

public int getNumProducts(int index)
{
if(this.results== null)
{
this.results = new ArrayList();
}
while(index >= this.results.size())
{
this.results.add(new Product());
}

Product p = (Product) results.get(index);
return p.getNumProducts();
}
Brent Sterling
Ranch Hand

Joined: Feb 08, 2006
Posts: 948
I took a look at your code and nothing jumps out at me. Do you know exactly where the NPE is coming from? Are you able to step through the code in a debugger? A NPE could be caused by a number of lines (if your action mapping does not have a name attribute, if user is null, if user.getOrder return null, maybe within user.getOrder, etc.).

Is the exception thrown when the page is being displayed or when the user submits the page? This appears to be the Action that is used to display the page. Do you have another action that is used to save the changes?

I also would expect to see code in your display action that populated fields on your form. It looks like you get the data off the session and then don't do anything with it. I don't know if your "while(count < results.size())" loop is just in there for debugging. Should you be calling "skuform.setResults(products)" before the loop?

The following items are not critical....but I wanted to throw them in.

The method getNumProducts(int index) is probably not needed...or at least it will not be called by Struts.

I find it easier to have method like this:
public void setResultList(ArrayList results)
public ArrayList getResultList()
public Product getResultItem(int index)

resulting in jsp code like this:
<logic:iterate name="SkuSearchForm" property="resultList" id="resultItem">

- Brent
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
Originally posted by Brent Sterling:
I took a look at your code and nothing jumps out at me. Do you know exactly where the NPE is coming from? Are you able to step through the code in a debugger? A NPE could be caused by a number of lines (if your action mapping does not have a name attribute, if user is null, if user.getOrder return null, maybe within user.getOrder, etc.).

Is the exception thrown when the page is being displayed or when the user submits the page? This appears to be the Action that is used to display the page. Do you have another action that is used to save the changes?

I also would expect to see code in your display action that populated fields on your form. It looks like you get the data off the session and then don't do anything with it. I don't know if your "while(count < results.size())" loop is just in there for debugging. Should you be calling "skuform.setResults(products)" before the loop?

The following items are not critical....but I wanted to throw them in.

The method getNumProducts(int index) is probably not needed...or at least it will not be called by Struts.

I find it easier to have method like this:
public void setResultList(ArrayList results)
public ArrayList getResultList()
public Product getResultItem(int index)

resulting in jsp code like this:
<logic:iterate name="SkuSearchForm" property="resultList" id="resultItem">

- Brent


Null pointer exception happens when I submit the form. The part that might indicate where the problem is is that it does not occur if I submit a form with an ArrayList of size 0.

This action is to both display the page and save the page (perhaps I am completely mis-understanding this and this is the root of my problem)


I don't know if your "while(count < results.size())" loop is just in there for debugging.

That loop is there so that I can go through all of the values that have been submitted. I cut it down to that to try and reduce the possible points of failure. In the end what I want to do is go through each of the values that have been submitted by the user (in the form) and check to see which of those have a specific elements that have a value that is not 0. For all of those that are not 0 I want to add them to the ArrayList that is stored in the ArrayList that is stored in Session (in the order page).

Should you be calling "skuform.setResults(products)" before the loop?

Would that not defeat the purpose that I outlined above ?

The last note is how important are the names of the methods to struts ? Must the names of the methods match to something specifically in order for them to work ?

Thanks once again for all your time and most importantly patience on these questions.
Brent Sterling
Ranch Hand

Joined: Feb 08, 2006
Posts: 948
My first suggestion would be to find out exactly what is causing the exception. You can use logging (log4j or system.out.println) if you cannot connect with a debugger. If you are getting into your action on the submit then the indexed properties worked and your form should be populated.

I would typically have a display action and a save action. The display action would pull the data from the database (or the session in your case) and populate the form. The save action would take the submitted values from form and save them to the database (or back to the session).

The names are not critical to Struts, but to me is confusing to have one version of getResults that returns a collection and another version of getResults that returns a single object. You could have getResults and getResult but the difference is subtle (with just the "s" difference).

- Brent
[ October 17, 2006: Message edited by: Brent Sterling ]
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
I have been trying to narrow down the exception, and reduced the action involved with submitting the form down to doing nothing but mapping for success. I am going to try and explain my logic before I get into the issue (this usually helps me clear up my problems myself anyways) When a user clicks on search this page will be brought up. There is a form that they can use to enter what they are searching for, which will eventually be linked to a database in the background). After they click submit the same page is returned only now it the search form as well as another form which will show the results of the search. The results are the products that match their search, and they are named results. When I go to submit the "results" it works fine when there was no results from the search, otherwise I now get an out of bounds exception error for any number that is not zero. Hopefully this might point someone to where I am making a mistake.

I should also point out that I have tried to point the success to a page that is nothing more than an information page and still get the array out of bounds exception when the action class does nothing other than forward on to the success class.

thanks again for all the time and patience.
[ October 18, 2006: Message edited by: A knibbs ]
Brent Sterling
Ranch Hand

Joined: Feb 08, 2006
Posts: 948
Now that I think about it...you might be hitting an issue that my project encountered when we migrated from Java 1.3 to 1.4. It is mentioned in the wiki article in the section titled "BeanUtils Indexed Properties Issue". Here is a link to the issue:

http://issues.apache.org/bugzilla/show_bug.cgi?id=28358

I don't fully understand the issue but I think you can get around it by either changing the names of your methods or changing the return of getResults from ArrayList to Collection. The wiki article mentioned returning an array, but I have never done that.

http://wiki.apache.org/struts/StrutsCatalogLazyList

- Brent
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
I don't quite understand this, but I just started reading. What does the name change that you are suggesting entail ?
Thanks once again.
It is nice to know that this might not have been entirely my fault for the reason that it doesn't work.
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
I suspect that has a pretty good chance of being the problem. I have tried a couple of things the most important one being using the page normally but omitting the portion of the form that uses the indexedproperty. All of a sudden my page worked (well the small amount of if that was left after trying to narrow down possible sources of errors.) I would love to hear what your thought was regarding namechance as stated before, as changing to collections would be a rather large headache compared to simply changing a few method names.
Thanks again for all the help thus far.

I don't know if it matters or not but thought that I would throw it in anyways. When the page first starts it is just the single form waiting for text to search for. When this search box has data entered it is submitted and then the page is re-displayed with the search box (with the value that was entered into the box still there as well as a form with all the results that came from the query. Now the user has to enter the number of specific items they are looking to acquire. This is when it is submitted yet again an comes back with the values still in the each product as well as the values in the search field.

A side note to that question is that seeing as how the forms are in request scope does that mean that I won't be able to access them from one submit to the other ? Not sure if that makes any sense this entire problem has been getting on my nerves a little more each day.

thanks for all the patience you have all shown me.
[ October 18, 2006: Message edited by: A knibbs ]
Brent Sterling
Ranch Hand

Joined: Feb 08, 2006
Posts: 948
The name change would be to use pairs like getResult and getResults, or getResultItem and getResultList. Just so that you did not have the same method name for both.

Also, it would likely be pretty easy to change your methods around to use Collection instead of ArrayList. In general it is better practice to have your methods use the interfaces like List and Collection than the concrete classes like ArrayList.

- Brent
A knibbs
Ranch Hand

Joined: Aug 23, 2006
Posts: 158
Have thought of 1 other issue that may be important for this problem. All of my forms are declared in request scope. So after the search is preformed there are 2 forms on the page. The search one and the results one. The results one being populated by the searchAction. Does this not mean that when the resultsAction goes to work there is no data left as it doesn't have a form ?

Also I thought I would include if this is an abnormal way of doing things and there is a better/more standard way of doing things I am not tied to doing it in one particular manner, I would simply like to get this working.


thanks once again for all the help/suggestions/ideas that you have provided to me.
[ October 19, 2006: Message edited by: A knibbs ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Struts 1.2.9 +text areas.
 
Similar Threads
Clearing of Struts forms on reset
Uncehecking a checked property
Trials and tribulations, trys and catches
enctype="multipart/form-data" request.getParameter() issue
Struts html:radio Question