You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by "David M. Karr" <dm...@earthlink.net> on 2001/09/29 23:00:11 UTC

link to list page & Resetting list page after saving in edit page

Tomcat3.2.3 (with JBoss2.4.1).

I have several architectural and technical issues I'm trying to resolve with a
quite simple page arrangement.  I'd appreciate any guidance, both towards
fixing what I have, and producing a more "sane" arrangement, if there's
something basicallywrong with my architecture.

I have a main page (called "/main/main.jsp"), with an ordinary link to a second
page (called "/class/listClasses.jsp".

The second page will contain a table listing the fields of all the instances of
a particular domain class (represented by an EJB entity).  Each row of the
table will print a string for each field, and also contain an "Edit" submit
button.  Each table row is inside a "html:form" tag.

Pressing the Edit button will go a third page ("/class/editClass.jsp")
containing text fields containing the existing values associated with the row.
The form the fields are in also contains a "Save" button.

Pressing the "Save" button will save the changes to the EJB and return to the
"listClasses" page, refreshing the information.

I have three actions defined in my "struts-config.xml".  The "editClass" action
is the "action" on each of the "html:form"s (for each table row) in
"listClasses.jsp".

The "saveClass" action is the "action" on the "html:form" in "editClass.jsp".

The third action (actually, the first one, chronologically) is the one that is
giving me trouble.  This action should be executed from an "html:link" on
"main.jsp", so it goes to "listClasses.jsp".

Here's my struts-config.xml, with two choices for the "listClasses" action, one
being commented out.

------------------------------
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
  "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">
<struts-config>
 <form-beans>
  <form-bean name="listClassesForm" type="com.intsoft.sgs.web.forms.ListClassesForm"/>
  <form-bean name="editClassForm" type="com.intsoft.sgs.web.forms.EditClassForm"/>
  <form-bean name="saveClassForm" type="com.intsoft.sgs.web.forms.SaveClassForm"/>
 </form-beans>
 <action-mappings>
  <action path="/class/listClasses" name="listClassesForm"
			 forward="/class/listClasses.jsp"
			 scope="session">
  </action>
<!--
  <action path="/class/listClasses" name="listClassesForm"
			 scope="request"
			 type="com.intsoft.sgs.web.actions.ListClassesAction">
   <forward name="success" path="/class/listClasses.jsp"/>
  </action>
-->
  <action path="/class/editClass" name="editClassForm"
			 scope="request"
			 type="com.intsoft.sgs.web.actions.EditClassAction">
   <forward name="success" path="/class/editClass.jsp"/>
  </action>
  <action path="/class/saveClass" name="saveClassForm"
          scope="request"
			 type="com.intsoft.sgs.web.actions.SaveClassAction">
   <forward name="success" path="/class/listClasses.jsp"/>
  </action>
 </action-mappings>
</struts-config>
------------------------------

When I have it this way, I click the link in "main.jsp" and I see the
ListClassesForm object get created, and the "reset()" method called (which is
where I presently get the list of objects), and the "listClasses.jsp" displays
correctly.  I then click the "Edit" button on a row, and I see the
"EditClassForm" object get created, and the "editClass.jsp" page displays
correctly.  I then change one of the field values and click "Save".  This goes
back to "listClasses.jsp".  Unfortunately, it still has the old list contents.
If I got back to "main.jsp" and click the "listClasses" link, then
"listClasses.jsp" shows up with the new contents.

So, now I redeploy it, switching the two "listClasses" actions, so the one with
the "forward" attribute is commented out, in favor of the one with the "type"
attribute and the "forward" sub-element.

When I reexecute this deployment, and I click on the "listClasses" link in
"main.jsp", I go to a blank page.  The URL says
"http://localhost:8080/sgs/class/listClasses.do" (which is the same as in the
other deployment), but the page is completely blank.

Note that in the first deployment, I see a "In ListClassesForm.reset()"
message, but not a "In ListClassesAction.perform()" message.

In the second deployment, I see a "In ListClassesAction.perform()" message, but
not the other.  In addition, in the "perform()" method, I also print out the
return from "servlet.findForward()" for "success", and that returns "null".
Notice that I have a "forward" sub-element in that action (the one you see
presently commented out above).

I'll also include my "ListClassesAction" and "ListClassesForm" classes here
(skipping the "package" and "import"s).

---------------
public final class ListClassesAction extends Action
{
    public ActionForward perform(ActionMapping        mapping,
                                 ActionForm           form,
                                 HttpServletRequest   request,
                                 HttpServletResponse  response)
       throws IOException, ServletException
   {
      System.out.println("In ListClassesAction.perform().");
      System.out.println("form[" + form + "]");
      if (form != null)
      {
         ListClassesForm   listClassesForm   = (ListClassesForm) form;
         System.out.println("Getting all classes.");
         listClassesForm.setAllClasses(ClassDAO.getAllClasses());
         System.out.println("Got all classes.");
      }
      
      ActionForward  actionForward  = servlet.findForward("success");
      System.out.println("actionForward[" + actionForward + "]");
      return (actionForward);
//       return (servlet.findForward("success"));
   }
}
---------------

---------------
public final class ListClassesForm extends ActionForm
{
   private  Collection  _allClasses = null;

   public   Collection  getAllClasses() { return (_allClasses); }
   
   public   void  setAllClasses(Collection allClasses)
   { _allClasses = allClasses; }

   public   void  reset(ActionMapping mapping, HttpServletRequest request)
   {
      System.out.println("In ListClassesForm.reset().");
      setAllClasses(ClassDAO.getAllClasses());
   }
}
---------------

-- 
===================================================================
David M. Karr          ; Best Consulting
dmkarr@earthlink.net   ; Java/Unix/XML/C++/X ; BrainBench CJ12P (#12004)


Re: link to list page & Resetting list page after saving in edit page

Posted by "David M. Karr" <dm...@earthlink.net>.
>>>>> "martin" == martin cooper <ma...@tumbleweed.com> writes:

    >> It almost seems like "forwards" bypass actions.  When I did my "forward"
    martin> back
    >> to the list page, it wouldn't execute the "ListClassesAction.perform()"
    martin> method,
    >> which normally populates the list with new data.

    martin> Forwards go where you tell them to, and don't make any hidden detours.
    martin> Unless I'm mistaken, your forwards reference the JSP directly, which is why
    martin> they go to the JSP and not to the action. If you need them to go to the
    martin> action first, then you'll need to define them to do that (e.g. by specifying
    martin> "foo.do" instead of "foo.jsp" for the path).

    martin> Hope this helps.

Sigh.  I was fairly certain I had already tried this, but after I commented out
my manual setting of the "listClasses" bean (in SaveClassAction) and changed
the "forward" element in "struts-config.xml" to point to "listClasses.do"
instead of "listClasses.jsp", it worked fine.

-- 
===================================================================
David M. Karr          ; Best Consulting
dmkarr@earthlink.net   ; Java/Unix/XML/C++/X ; BrainBench CJ12P (#12004)


Re: link to list page & Resetting list page after saving in edit page

Posted by ma...@tumbleweed.com.
> It almost seems like "forwards" bypass actions.  When I did my "forward"
back
> to the list page, it wouldn't execute the "ListClassesAction.perform()"
method,
> which normally populates the list with new data.

Forwards go where you tell them to, and don't make any hidden detours.
Unless I'm mistaken, your forwards reference the JSP directly, which is why
they go to the JSP and not to the action. If you need them to go to the
action first, then you'll need to define them to do that (e.g. by specifying
"foo.do" instead of "foo.jsp" for the path).

Hope this helps.

--
Martin Cooper


----- Original Message -----
From: <dm...@earthlink.net>
To: <st...@jakarta.apache.org>
Sent: Saturday, September 29, 2001 11:38 PM
Subject: Re: link to list page & Resetting list page after saving in edit
page


> >>>>> "David" == David M Karr <dm...@earthlink.net> writes:
>
> >>>>> "David" == David M Karr <dm...@earthlink.net> writes:
>     David> Tomcat3.2.3 (with JBoss2.4.1).
>     David> I have several architectural and technical issues I'm trying to
resolve with a
>     David> quite simple page arrangement.  I'd appreciate any guidance,
both towards
>     David> fixing what I have, and producing a more "sane" arrangement, if
there's
>     David> something basicallywrong with my architecture.
>
>     David> Update:
>
>     David> I realized that my "perform" method was looking for the
"forward" in the
>     David> servlet, instead of the ActionMapping.  Once I fixed that, the
initial display
>     David> of the class list worked fine.
>
>     David> Then, I clicked one of the Edit buttons, changed one of the
fields, clicked the
>     David> Save button, and it displayed the following error:
>
> Well, I ended up adding code in my "SaveClassAction" class which just
manually
> gets the "listClassesForm" attribute from the session, and then updates
the
> attribute on it manually, then continues with the forward.  That correctly
> updates the list after I click "Save".
>
> It almost seems like "forwards" bypass actions.  When I did my "forward"
back
> to the list page, it wouldn't execute the "ListClassesAction.perform()"
method,
> which normally populates the list with new data.
>
> Is there a cleaner strategy for doing things like this?  I definitely
didn't
> like to hardcode the reference to "listClassesForm" in the
> "SaveClassAction.perform*()" method.  I wish I could have gotten some sort
of
> indirect reference to the form bean associated with the page I was going
to
> forward to.
>
> --
> ===================================================================
> David M. Karr          ; Best Consulting
> dmkarr@earthlink.net   ; Java/Unix/XML/C++/X ; BrainBench CJ12P (#12004)
>



Re: link to list page & Resetting list page after saving in edit page

Posted by "David M. Karr" <dm...@earthlink.net>.
>>>>> "David" == David M Karr <dm...@earthlink.net> writes:

>>>>> "David" == David M Karr <dm...@earthlink.net> writes:
    David> Tomcat3.2.3 (with JBoss2.4.1).
    David> I have several architectural and technical issues I'm trying to resolve with a
    David> quite simple page arrangement.  I'd appreciate any guidance, both towards
    David> fixing what I have, and producing a more "sane" arrangement, if there's
    David> something basicallywrong with my architecture.

    David> Update:

    David> I realized that my "perform" method was looking for the "forward" in the
    David> servlet, instead of the ActionMapping.  Once I fixed that, the initial display
    David> of the class list worked fine.

    David> Then, I clicked one of the Edit buttons, changed one of the fields, clicked the
    David> Save button, and it displayed the following error:

Well, I ended up adding code in my "SaveClassAction" class which just manually
gets the "listClassesForm" attribute from the session, and then updates the
attribute on it manually, then continues with the forward.  That correctly
updates the list after I click "Save".

It almost seems like "forwards" bypass actions.  When I did my "forward" back
to the list page, it wouldn't execute the "ListClassesAction.perform()" method,
which normally populates the list with new data.

Is there a cleaner strategy for doing things like this?  I definitely didn't
like to hardcode the reference to "listClassesForm" in the
"SaveClassAction.perform*()" method.  I wish I could have gotten some sort of
indirect reference to the form bean associated with the page I was going to
forward to.

-- 
===================================================================
David M. Karr          ; Best Consulting
dmkarr@earthlink.net   ; Java/Unix/XML/C++/X ; BrainBench CJ12P (#12004)


Re: link to list page & Resetting list page after saving in edit page

Posted by "David M. Karr" <dm...@earthlink.net>.
>>>>> "David" == David M Karr <dm...@earthlink.net> writes:

    David> Tomcat3.2.3 (with JBoss2.4.1).
    David> I have several architectural and technical issues I'm trying to resolve with a
    David> quite simple page arrangement.  I'd appreciate any guidance, both towards
    David> fixing what I have, and producing a more "sane" arrangement, if there's
    David> something basicallywrong with my architecture.

Update:

I realized that my "perform" method was looking for the "forward" in the
servlet, instead of the ActionMapping.  Once I fixed that, the initial display
of the class list worked fine.

Then, I clicked one of the Edit buttons, changed one of the fields, clicked the
Save button, and it displayed the following error:

---------------------
Error: 500
Location: /sgs/class/listClasses.jsp
Internal Servlet Error:

javax.servlet.ServletException: Cannot find bean listClassesForm in scope null
	at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:459)
	at c_00025ass._0002fclass_0002flistClasses_0002ejsplistClasses_jsp_31._jspService(_0002fclass_0002flistClasses_0002ejsplistClasses_jsp_31.java:459)
   ...
---------------------

I'm not completely certain what the effect of the 'scope="request"' attribute
in the "action" element, but I thought this might be related to this.  So, I
changed it to "session" and redeployed.

Now, after clicking "Save", it didn't get the error, and it redisplayed the
class list page, but without showing the change in content.  It seems like
forwarding to "listClasses" through the forward list didn't execute the
Action's "perform" method, which automatically updates the list of classes.  Is
this expected?  What should be the correct procedure to get the list refreshed?

Note that I also commented out the line in my ActionForm.reset() method which
updates the class list.  I'm now doing that in the "Action.perform()" method,
which I believe is more correct.

For more context, I'll leave the excerpts from my original note showing the
"struts-config.xml" and the Action and Form classes (before I fixed the
"forward" reference and commented out the line in the Form class).

    David> Here's my struts-config.xml, with two choices for the "listClasses" action, one
    David> being commented out.

    David> ------------------------------
    David> <?xml version="1.0" encoding="ISO-8859-1" ?>
    David> <!DOCTYPE struts-config PUBLIC
    David>   "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
    David>   "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">
    David> <struts-config>
    David>  <form-beans>
    David>   <form-bean name="listClassesForm" type="com.intsoft.sgs.web.forms.ListClassesForm"/>
    David>   <form-bean name="editClassForm" type="com.intsoft.sgs.web.forms.EditClassForm"/>
    David>   <form-bean name="saveClassForm" type="com.intsoft.sgs.web.forms.SaveClassForm"/>
    David>  </form-beans>
    David>  <action-mappings>
    David>   <action path="/class/listClasses" name="listClassesForm"
    David> 			 forward="/class/listClasses.jsp"
    David> 			 scope="session">
    David>   </action>
    David> <!--
    David>   <action path="/class/listClasses" name="listClassesForm"
    David> 			 scope="request"
    David> 			 type="com.intsoft.sgs.web.actions.ListClassesAction">
    David>    <forward name="success" path="/class/listClasses.jsp"/>
    David>   </action>
    --> 
    David>   <action path="/class/editClass" name="editClassForm"
    David> 			 scope="request"
    David> 			 type="com.intsoft.sgs.web.actions.EditClassAction">
    David>    <forward name="success" path="/class/editClass.jsp"/>
    David>   </action>
    David>   <action path="/class/saveClass" name="saveClassForm"
    David>           scope="request"
    David> 			 type="com.intsoft.sgs.web.actions.SaveClassAction">
    David>    <forward name="success" path="/class/listClasses.jsp"/>
    David>   </action>
    David>  </action-mappings>
    David> </struts-config>
    David> ------------------------------
    David> ---------------
    David> public final class ListClassesAction extends Action
    David> {
    David>     public ActionForward perform(ActionMapping        mapping,
    David>                                  ActionForm           form,
    David>                                  HttpServletRequest   request,
    David>                                  HttpServletResponse  response)
    David>        throws IOException, ServletException
    David>    {
    David>       System.out.println("In ListClassesAction.perform().");
    David>       System.out.println("form[" + form + "]");
    David>       if (form != null)
    David>       {
    David>          ListClassesForm   listClassesForm   = (ListClassesForm) form;
    David>          System.out.println("Getting all classes.");
    David>          listClassesForm.setAllClasses(ClassDAO.getAllClasses());
    David>          System.out.println("Got all classes.");
    David>       }
      
    David>       ActionForward  actionForward  = servlet.findForward("success");
    David>       System.out.println("actionForward[" + actionForward + "]");
    David>       return (actionForward);
    David> //       return (servlet.findForward("success"));
    David>    }
    David> }
    David> ---------------

    David> ---------------
    David> public final class ListClassesForm extends ActionForm
    David> {
    David>    private  Collection  _allClasses = null;

    David>    public   Collection  getAllClasses() { return (_allClasses); }
   
    David>    public   void  setAllClasses(Collection allClasses)
    David>    { _allClasses = allClasses; }

    David>    public   void  reset(ActionMapping mapping, HttpServletRequest request)
    David>    {
    David>       System.out.println("In ListClassesForm.reset().");
    David>       setAllClasses(ClassDAO.getAllClasses());
    David>    }
    David> }
    David> ---------------


-- 
===================================================================
David M. Karr          ; Best Consulting
dmkarr@earthlink.net   ; Java/Unix/XML/C++/X ; BrainBench CJ12P (#12004)