Struts ActionForm Lost from Request scope

I’ve taken over maintenance of a 10-year-old Struts 1.2 application. (It’s way too complicated and proprietary to post.)

The application uses a couple of ActionForms which were formerly stored in the session. Because the latest change request requires that we open multiple ActionForms at the same time, I’ve changed the configuration of the ActionForm from session scope to request scope with struts-config.

This change breaks some custom tag code that looks for the ActionForm within the PageContext object. (And it may break other functionality that we have not been able to test because of this error.)

The code is looking for the ActionForm with TagUtils.getRealValueFromBean

I’ve tried tweaking parameters in this call to specify the request scope and tried looking within the request object’s attributes but the ActionForm is not there! Java code within the JSP shows no such attribute within the Request object. (I’ve heard that a refresh event can create a new ActionForm but here there’s no ActionForm whatsoever within the Request object. And yet, at the bottom of the Action that retrieves the object from the database, the ActionForm is present within the Request object.

I created a small test application with an ActionForm that can be configured in either session or request scope, but the retrieval of the ActionForm from Request works fine!

Any idea of where/how to track down how the ActionForm is getting clobbered?

Or else how to support multiple instances of ActionForm while keeping scope=session?

Answer

You can try the following:

Assuming scope="session" and Foo as my domain class:

public class Foo {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Then:

  • In the ActionForm:

    private static Map map = new HashMap();
    
    public Foo getFoo(String page) {
        if (!map.containsKey(page)) {
            map.put(page, new Foo());
        }
        return (Foo) map.get(page);
    }
    
    public void setFoo(String page, Foo foo) {
        map.put(page, foo);
    }
    
  • Input JSP

    <html:text property="foo(page1).name" />
    

    Where page1 is an arbitrary name, e.g.: the name of your current page. foo(page1).name is the name of the property, so that it is automatically populated by Struts when it is sent to the server.

  • Output JSP

    • With Expression Language (EL):

      ${TestForm.getFoo('page1').name}
      
    • With Struts:

      <bean:write name="TestForm" property="foo(page1).name" />
      

    Where TestForm is the name of my ActionForm (defined in the struts-config.xml file).

Leave a Reply

Your email address will not be published. Required fields are marked *