Here is my test code:

public class HomePage extends WebPage {

    private static final long serialVersionUID = 1L;

    private String word;

    public HomePage(final PageParameters parameters) {

        add(new FeedbackPanel("feedback") {
            private static final long serialVersionUID = 1L;
            @Override protected void onBeforeRender() {
                System.out.println("= = = = FeedbackPanel
onBeforeRender()");
                   System.out.println("         FeedbackbackMessageModel = "
+ getFeedbackMessagesModel().getObject());
                super.onBeforeRender();
            }
        }.setOutputMarkupPlaceholderTag(true));
        // if the word "blowup" is entered,
        //this register a error message and throw new
AbstractRestartResponseException()
        IModel model = new Model() {
            private static final long serialVersionUID = 1L;
            @Override public Object getObject() {
                if (word != null && word.equals("blowup")) {
                    word = "-w-e-b-l-e-w-u-p-";
                    HomePage.this.fatal("[2/2]This message is from
Model.");     // why this is NOT render in Ajax?
                    getPage().detach();
                    System.out.println("! ! ! ! ! throwing  new
AbstractRestartResponseException()");
                    throw new AbstractRestartResponseException() {
                        private static final long serialVersionUID = 1L;
                    };
                } else {
                    return "The word is: \"" + (word == null ? " n u l l " :
word) + "\"";
                }
            }
        };
        add(new Label("message", model) {
            private static final long serialVersionUID = 1L;
            @Override protected void onBeforeRender() {
                System.out.println("= = = = Label onBeforeRender(), model =
" + getModel().getObject());
                super.onBeforeRender();
            }
        }.setOutputMarkupId(true));
        Form form = new Form("form", new CompoundPropertyModel(this));
        add(form);
        form.add(new TextField("word").setRequired(true));
        AjaxFallbackButton submitButton = new
AjaxFallbackButton("submitButton", form) {
            private static final long serialVersionUID = 1L;
            @Override protected void onSubmit(AjaxRequestTarget target, Form
f) {
                if (word != null && word.equals("blowup")) {
                    HomePage.this.error("[1/2]This message is from onSubmit.
There should also be a message from model");
                }
                if (target != null) {
                    target.addComponent(HomePage.this.get("feedback"));
    // clear error feedback if any
                    target.addComponent(HomePage.this.get("message"));
                }
            }

            @Override protected void onError(AjaxRequestTarget target, Form
f) {
                target.addComponent(HomePage.this.get("feedback"));
// show updated error feedback
            }
        };
        form.add(submitButton);
    }
}

Things work perfectly in non-Ajax.  But in Ajax, after 'throw new
AbstractRestartResponseException()' in model, the Ajax response to the
browser is wrong in two places.  1) the feedback component don't have the
second message register in the model, only the message from onSubmit(target)
show. 2) the Ajax response is missing the second half:  no Label component
and the </ajax-response> end tag.

===== This is the normal Ajax response copy from the debug panel:

INFO: Received ajax response (257 characters)
INFO:
<?xml version="1.0" encoding="UTF-8"?><ajax-response><component
id="feedback4" ><![CDATA[<span id="feedback4">

</span>]]></component><component id="message1" ><![CDATA[<span
id="message1">The word is: "bla"</span>]]></component></ajax-response>
INFO: Response parsed. Now invoking steps...
INFO: Response processed successfully.

===== This is the Ajax response after 'throw new
AbstractRestartResponseException()':

INFO: Received ajax response (339 characters)
INFO:
<?xml version="1.0" encoding="UTF-8"?><ajax-response><component
id="feedback4"  encoding="wicket1" ><![CDATA[<span id="feedback4">
  <ul>
    <li class="feedbackPanelERROR">
      <span class="feedbackPanelERROR">[1/2]^This message is from onSubmit.
There should also be a message from model</span>
    </li>
  </ul>
</span>]]></component>
ERROR: Error while parsing response: Could not find root <ajax-response>
element
INFO: Invoking post-call handler(s)...
INFO: Invoking failure handler(s)...

>From tracing the wicket code, I just don't see how this can be.  I see
AjaxResponseTarget#response() is called again, and
response.write("</ajax-response>");
is called on line 539.  But in the end the Ajax response is wrong.

What is wrong?  Is this a bug?


Here is the WicketApplication for the non-Ajax case:

public class WicketApplication extends WebApplication
{
    public WicketApplication() {
    }

    public Class<? extends WebPage> getHomePage() {
        return HomePage.class;
    }


    @Override public RequestCycle newRequestCycle(Request request, Response
response) {
        return new WebRequestCycle(this, (WebRequest) request, (WebResponse)
response) {
            @Override public Page onRuntimeException(Page page,
RuntimeException e) {
                // page can be null
                if (page == null) {
                    return super.onRuntimeException(page, e);
                }
                return page;
            }
        };
    }

}

Reply via email to