You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wicket.apache.org by Patrick Schwarzer <Pa...@tomtec.de> on 2018/11/14 08:36:38 UTC

Redirect after Response has been written

Dear Sir or Madam,

we having a specific problem in using Wicket 7.10, creating an Ajax-Response with multiple <ajax-response> entries.

In our application, we are using onRequestHandlerResolved to do some initialization stuff and onRequestHandlerExecuted to save changes done on our data during requestHandlerExecutor.execute().
For this purpose, we have created an own AbstractRequestCycleListener which overwrites both methods and calls our specific code.

RequestCycle:
private void execute(IRequestHandler handler)
{
try
{
  listeners.onRequestHandlerResolved(this, handler);
  requestHandlerExecutor.execute(handler);
  listeners.onRequestHandlerExecuted(this, handler);
}
catch (RuntimeException e)
{
}
}

Our problem is, that an Exception thrown in onRequestHandlerExecuted after requestHandlerExecutor.execute() has already created an ajax-response creates an invalid response:

Wicket.Ajax:  Wicket.Ajax.Call.failure: Error while parsing response: Error: Invalid XML: <?xml version="1.0" encoding="UTF-8"?>
<ajax-response>
                <!-- Result of requestHandlerExecutor.execute()  -->
</ajax-response>
<ajax-response>
                <!-Redirect to specific Exception Page, result of onRequestHandlerExecuted -->
                <redirect>
                               <![CDATA[./wicket/bookmarkable/our.package.ExceptionPage?locale=en]]>
                </redirect>
</ajax-response>

To solve our problem, we tried to clear the existing Response during exception in onRequestHandlerExecuted (RequestCycle.get().getResponse().reset()), but we are not able to clear the Response, created in requestHandlerExecutor.execute(), because wicket uses HeaderBufferingWebResponse  by default which did not allow to reset already created Response in encapsulated ServletWebResponse. Calling reset in HeaderBufferingWebResponse instead throws an IllegalStateException.

We think that the problem came from ServletWebResponse which simply adds multiple ajax-response entries to the HttpServletResponse which results in the mentioned, invalid XML.

ServletWebResponse:


@Override
public void sendRedirect(String url)
{
 try
 {
  if (webRequest.isAjax())
  {
   /*
    * usually the Ajax-Location header is enough and we do not need to the redirect url
    * into the response, but sometimes the response is processed via an iframe (eg
    * using multipart ajax handling) and the headers are not available because XHR is
    * not used and that is the only way javascript has access to response headers.
    */
   httpServletResponse.getWriter().write(
    "<ajax-response><redirect><![CDATA[" + url + "]]></redirect></ajax-response>");
  }
  else { }
 }
 catch (IOException e) {  }
}

My question is, how we could handle our problem when throwing an exception in onRequestHandlerExecuted? And how is it possible, that code run after requestHandlerExecutor.execute(), redirects correctly to exception page?
How we can run specific code, after the request has been processed, is there maybe another way instead of overwriting onRequestHandlerExecuted?

Kind regards

PATRICK SCHWARZER
SOFTWARE ENGINEER

o +49 89 32175 655

TOMTEC Imaging Systems GmbH
Edisonstrasse 6, 85716 Unterschleissheim, Germany, Managing Director:
Johannes Waldinger, Dr. Thomas Piehler, HRB 235646 Amtsgericht Muenchen

[cid:image002.jpg@01D47BF6.C69F58D0]<http://www.tomtec.de/>

_____________________________________________________________

RSNA | 11/25/2018 - 11/30/2018 | Chicago/USA
EuroEcho | 12/05/2018 - 12/08/2018 | Milan/Italy

Re: Redirect after Response has been written

Posted by Tobias Soloschenko <to...@googlemail.com.INVALID>.
Hello Mr. Schwarzer,

please use user@wicket.apache.org.

kind regards

Tobias

> Am 14.11.2018 um 09:36 schrieb Patrick Schwarzer <Pa...@tomtec.de>:
> 
> Dear Sir or Madam,
>  
> we having a specific problem in using Wicket 7.10, creating an Ajax-Response with multiple <ajax-response> entries.
>  
> In our application, we are using onRequestHandlerResolved to do some initialization stuff and onRequestHandlerExecuted to save changes done on our data during requestHandlerExecutor.execute().
> For this purpose, we have created an own AbstractRequestCycleListener which overwrites both methods and calls our specific code.
>  
> RequestCycle:
> private void execute(IRequestHandler handler)
> {
> try
> {
>   listeners.onRequestHandlerResolved(this, handler);
>   requestHandlerExecutor.execute(handler);
>   listeners.onRequestHandlerExecuted(this, handler);
> }
> catch (RuntimeException e)
> {
> }
> }
>  
> Our problem is, that an Exception thrown in onRequestHandlerExecuted after requestHandlerExecutor.execute() has already created an ajax-response creates an invalid response:
>  
> Wicket.Ajax:  Wicket.Ajax.Call.failure: Error while parsing response: Error: Invalid XML: <?xml version="1.0" encoding="UTF-8"?>
> <ajax-response>
>                 <!-- Result of requestHandlerExecutor.execute()  -->
> </ajax-response>
> <ajax-response>
>                 <!—Redirect to specific Exception Page, result of onRequestHandlerExecuted -->
>                 <redirect>
>                                <![CDATA[./wicket/bookmarkable/our.package.ExceptionPage?locale=en]]>
>                 </redirect>
> </ajax-response>
>  
> To solve our problem, we tried to clear the existing Response during exception in onRequestHandlerExecuted (RequestCycle.get().getResponse().reset()), but we are not able to clear the Response, created in requestHandlerExecutor.execute(), because wicket uses HeaderBufferingWebResponse  by default which did not allow to reset already created Response in encapsulated ServletWebResponse. Calling reset in HeaderBufferingWebResponse instead throws an IllegalStateException.
>  
> We think that the problem came from ServletWebResponse which simply adds multiple ajax-response entries to the HttpServletResponse which results in the mentioned, invalid XML.
>  
> ServletWebResponse:
>  
> @Override
> public void sendRedirect(String url)
> {
>  try
>  {
>   if (webRequest.isAjax())
>   {
>    /*
>     * usually the Ajax-Location header is enough and we do not need to the redirect url
>     * into the response, but sometimes the response is processed via an iframe (eg
>     * using multipart ajax handling) and the headers are not available because XHR is
>     * not used and that is the only way javascript has access to response headers.
>     */
>    httpServletResponse.getWriter().write(
>     "<ajax-response><redirect><![CDATA[" + url + "]]></redirect></ajax-response>");
>   }
>   else { }
>  }
>  catch (IOException e) {  }
> }
>  
> My question is, how we could handle our problem when throwing an exception in onRequestHandlerExecuted? And how is it possible, that code run after requestHandlerExecutor.execute(), redirects correctly to exception page?
> How we can run specific code, after the request has been processed, is there maybe another way instead of overwriting onRequestHandlerExecuted?
>  
> Kind regards
>  
> PATRICK SCHWARZER
> SOFTWARE ENGINEER
> 
> o +49 89 32175 655
> 
> TOMTEC Imaging Systems GmbH
> Edisonstrasse 6, 85716 Unterschleissheim, Germany, Managing Director:
> Johannes Waldinger, Dr. Thomas Piehler, HRB 235646 Amtsgericht Muenchen
> 
> 
> 
> _____________________________________________________________
> 
> RSNA | 11/25/2018 - 11/30/2018 | Chicago/USA
> EuroEcho | 12/05/2018 - 12/08/2018 | Milan/Italy

Re: Redirect after Response has been written

Posted by Martin Grigorov <mg...@apache.org>.
Hi,

On Wed, Nov 14, 2018 at 10:39 AM Patrick Schwarzer <
Patrick.Schwarzer@tomtec.de> wrote:

> Dear Sir or Madam,
>
>
>
> we having a specific problem in using Wicket 7.10, creating an
> Ajax-Response with multiple <ajax-response> entries.
>
>
>
> In our application, we are using *onRequestHandlerResolved* to do some
> initialization stuff and *onRequestHandlerExecuted* to save changes done
> on our data during *requestHandlerExecutor*.*execute()*.
>
> For this purpose, we have created an own AbstractRequestCycleListener
> which overwrites both methods and calls our specific code.
>
>
>
> RequestCycle:
>
> *private void *execute(IRequestHandler handler)
> {
>
> *try *{
>   *listeners*.onRequestHandlerResolved(*this*, handler);
>   *requestHandlerExecutor*.execute(handler);
>   *listeners*.onRequestHandlerExecuted(*this*, handler);
> }
> *catch *(RuntimeException e)
> {
> }
> }
>
>
>
> Our problem is, that an Exception thrown in *onRequestHandlerExecuted *after
> *requestHandlerExecutor*.*execute()* has already created an ajax-response
> creates an invalid response:
>
>
>
> Wicket.Ajax:  Wicket.Ajax.Call.failure: Error while parsing response:
> Error: Invalid XML: <?xml version="1.0" encoding="UTF-8"?>
>
> <ajax-response>
>
>                 <!-- Result of *requestHandlerExecutor*.*execute() * -->
>
> </ajax-response>
>
> <ajax-response>
>
>                 <!—Redirect to specific Exception Page, result of *onRequestHandlerExecuted
> -->*
>
>                 <redirect>
>
>
> <![CDATA[./wicket/bookmarkable/our.package.ExceptionPage?locale=en]]>
>
>                 </redirect>
>
> </ajax-response>
>
>
>
> To solve our problem, we tried to clear the existing Response during
> exception in *onRequestHandlerExecuted
> (RequestCycle.get().getResponse().reset()), *but we are not able to clear
> the Response, created in *requestHandlerExecutor*.*execute()*, because
> wicket uses HeaderBufferingWebResponse  by default which did not allow to
> reset already created Response in encapsulated ServletWebResponse. Calling
> reset in HeaderBufferingWebResponse instead throws an IllegalStateException.
>

If it throws IllegalStateException then it is too late to replace the
response because it is already flushed to the native servlet response.
The only thing you can do here is to try/catch your logic that is executed
in  *requestHandlerExecutor*.*execute().*
Or you can move this logic somewhere else where it will be executed earlier
than the flush of the response.


>
> We think that the problem came from ServletWebResponse which simply adds
> multiple ajax-response entries to the HttpServletResponse which results in
> the mentioned, invalid XML.
>
>
>
> ServletWebResponse:
>
>
>
> @Override
> *public void *sendRedirect(String url)
> {
>
> *try *{
>   *if *(*webRequest*.isAjax())
>   {
>
>
>
>
>
>
> */*    * usually the Ajax-Location header is enough and we do not need to the redirect url    * into the response, but sometimes the response is processed via an iframe (eg    * using multipart ajax handling) and the headers are not available because XHR is    * not used and that is the only way javascript has access to response headers.    */   **httpServletResponse*.getWriter().write(
>     *"<ajax-response><redirect><![CDATA[" *+ url + *"]]></redirect></ajax-response>"*);
>   }
>   *else *{ }
>  }
>  *catch *(IOException e) {  }
> }
>
>
>
> My question is, how we could handle our problem when throwing an exception
> in *onRequestHandlerExecuted*? And how is it possible, that code run
> after *requestHandlerExecutor*.*execute()*, redirects correctly to
> exception page?
>
> How we can run specific code, after the request has been processed, is
> there maybe another way instead of overwriting *onRequestHandlerExecuted*?
>
>
>
>
> Kind regards
>
>
>
> *PATRICK SCHWARZER*
> SOFTWARE ENGINEER
>
> *o* +49 89 32175 655
>
> *TOMTEC Imaging Systems GmbH*
> Edisonstrasse 6, 85716 Unterschleissheim, Germany, Managing Director:
> Johannes Waldinger, Dr. Thomas Piehler, HRB 235646 Amtsgericht Muenchen
>
> <http://www.tomtec.de/>
>
> _____________________________________________________________
>
> RSNA | 11/25/2018 - 11/30/2018 | Chicago/USA
> EuroEcho | 12/05/2018 - 12/08/2018 | Milan/Italy
>