Garth Dahlstrom wrote:

Hmm... going private or protected, fields must be added to the model via addModel or is there annotation to do it?


Yes you can add it to the model. Starting with 2.1.0 there is the option of using the Bindable annotation. However for backward compatibility Click defaults to using public fields. You can change this by passing "annotation" to the autobinding property:

<pages package="org.apache.click.examples.page" autobinding="annotation"/>

Then you can specify your fields as:

  @Bindable public String xyz;

Note the field is still declared public, however only those with Bindable annotations are considered.

Bindable is quite new in Click and there are plans to expand its functionality for finer grained control. You can view the details here: http://cwiki.apache.org/confluence/display/CLICK/Java+5+Support

Currently the documentation for Bindable is lacking a bit too.


When I try to use 'getContext().getRequestAttribute("app")', it always return null, which causes it to go into a redirect loop.


Strange, the following works for me:

  public class ForwardPage extends Page {

    public void onInit() {
      if (getContext().getRequestAttribute("app") == null) {
        getContext().setRequestAttribute("app", "default");
        setForward(this);
        // redirect to self without rendering...
      }
    }
  }

The first time the Page is hit, it sets the attribute and forwards to itself.

If you already know this just ignore otherwise: Forward in Click is the same as Forward in Servlets. In other words the same request is used in the forwarded Page, which is why the check for getRequestAttribute should work. However doing a redirect means a HTTP 304 is returned to the browser, which initiates another separate request to the server. Since this is a brand new request the "app" request attribute isn't present anymore.

Since you're using 2.1.0, the easiest option for redirect is probably the code you used in your original request:

  public RedirectPage extends Page{
    public void onInit() {

      // Note we check against the incoming request parameter,
      // not request attribute
      if (getContext().getRequestParameter("app") == null) {
        Map map = new HashMap();
        map.put("app", "default");
        setRedirect(RedirectPage.class, map);
        // redirect to self without rendering...
      }
    }
  }


I worked around it with the code below (autobinding on, 2.1.0RC1, Tomcat 6):

// Redirect /context/page -> /context/page?app=default before refreshing and rendering the page...
public class MyPage extends BorderPage {
    public String app = null;
...
public void onInit() {
if ((app == null || app.trim().length() == 0) && getContext().getSession().getAttribute("app") == null) {
                        Map params = new HashMap();
                        params.put("app", "default");
                        setRedirect(this.getClass(), params);
                        return;
                } else if (app != null) {
                        getContext().getSession().setAttribute("app", app);
                }

app = (String) getContext().getSession().getAttribute("app");
....

Hopefully that is helpful to others


You're approach above will certainly work too, but it means one will store the state in the users session.

Hope this helps.

kind regards

bob

Reply via email to