You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Martin Dietze <di...@fh-wedel.de> on 2013/02/18 17:55:37 UTC

Migration issue: page that writes binary data to the response

In the project I'm currently porting from 1.4.x to 6.6.0 I've
run into an issue with Wicket pages which stream binary data
into the WebResponse (e.g. ZIP archives created on the fly).

First thing I found was that obviously I *have* to create
templates for these pages even though they are not going to be
used for anything. 

The second thing is more serious: when writing to the response I
get an IllegalStateException as the template code has already
been written to it. This can be circumvented by calling
Response.reset() before Response.write() in my code. However in
development mode I still get an ISE as in Page.onAfterRender()
there's this code here:

| if (getApplication().getDebugSettings().isOutputMarkupContainerClassName())
| {
|     String className = Classes.name(getClass());
|     getResponse().write("<!-- Page Class ");
|     getResponse().write(className);
|     getResponse().write(" END -->\n");
| }
                                                                                                                                                }
Now of course I can write:

| @Override
| protected void onAfterRender() {
|   try { super.onAfterRender(); } catch (IllegalStateException e) { }
| }

... but I guess we agree that while this works it is far from nice.

I am not sure if I understand correctly what the above code is
trying to tell me. Does it mean that I am simply not supposed to
deliver my ZIP files by a Wicket page that way? 

If with today's Wicket version there's a different or even better
way to do this, which one would that be?

Else, would there be any harm in making the Page class more
friendly to this kind of use, by e.g. putting the above
if-statement into an overridable method and adding an option to
the Component class to tell it that there's no markup for it and
it should simply not expect any?

Cheers,

M'bert

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
My Hovercraft is full of eels!

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

Posted by Carl-Eric Menzel <cm...@wicketbuch.de>.
On Tue, 19 Feb 2013 09:23:28 +0100
Martin Dietze <di...@fh-wedel.de> wrote:

> IMO the problem is not that much how the response is generated,
> but how the component is already uses within the system. At
> this point creating a download link is simple as it simply is a
> BookmarkableLink to that page with the appropriate page
> parameters. Consequently, the download links are bookmarkable. 

You can mount shared resources just like you can mount pages, so they
can still be bookmarkable.	

Carl-Eric

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

Posted by Martin Dietze <di...@fh-wedel.de>.
On Tue, February 19, 2013, Martin Grigorov wrote:

> This is how it works.
> #replaceAllRequestHandlers() throws an exception to stop doing whatever it does at the moment.
> #scheduleRequestHandlerAfterCurrent() just appends a new RH to the list and executes it when all previous are executed.
> Since there is no need to wait for any other scheduled I think you can use #replaceAllRHs().
> 
> What is the problem ?

Thanks, I misunderstood the concept behind that exception and
caught it. Now everything is fine.

Cheers,

M'bert

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
New members urgently required for SUICIDE CLUB, Watford area.
                -- Monty Python's Big Red Book

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

Posted by Martin Grigorov <mg...@apache.org>.
On Tue, Feb 19, 2013 at 11:14 AM, Martin Dietze <di...@fh-wedel.de> wrote:

> On Tue, February 19, 2013, Martin Grigorov wrote:
>
> > You can use requestCycle.replaceAllRequestHandlers(new
> > ResourceRequestHandler(new ByteArrayResource(byteArray))) in your page
> code.
> > This will stop the page rendering and will return the byte[] from this
> > response. You can still configure the ByteArrayResource - filename,
> > disposition, etc.
>
> Thank you, I tried this (slightly corrected version):
>
> | RequestCycle.get().replaceAllRequestHandlers( new
> ResourceRequestHandler( new ByteArrayResource( mimeType, byteArray ), null
> ) );
>
> But this triggers a ReplaceHandlerException at
> RequestHandlerStack.replaceAll() as at that time
> RequestHandlerStack.requestHandlers is not empty.
>

This is how it works.
#replaceAllRequestHandlers() throws an exception to stop doing whatever it
does at the moment.
#scheduleRequestHandlerAfterCurrent() just appends a new RH to the list and
executes it when all previous are executed.
Since there is no need to wait for any other scheduled I think you can use
#replaceAllRHs().

What is the problem ?


>
> This actually looks weird to me as I'd expect a
> 'replaceAll' method to replace what is already
> there. Maybe a bug here?
>
> Cheers,
>
> M'bert
>
> --
> ----------- / http://herbert.the-little-red-haired-girl.org /
> -------------
> =+=
> No violence, gentlemen -- no violence, I beg of you! Consider the
> furniture!
>            -- Sherlock Holmes
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>


-- 
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com <http://jweekend.com/>

Re: Migration issue: page that writes binary data to the response

Posted by Martin Dietze <di...@fh-wedel.de>.
On Tue, February 19, 2013, Martin Grigorov wrote:

> You can use requestCycle.replaceAllRequestHandlers(new
> ResourceRequestHandler(new ByteArrayResource(byteArray))) in your page code.
> This will stop the page rendering and will return the byte[] from this
> response. You can still configure the ByteArrayResource - filename,
> disposition, etc.

Thank you, I tried this (slightly corrected version):

| RequestCycle.get().replaceAllRequestHandlers( new ResourceRequestHandler( new ByteArrayResource( mimeType, byteArray ), null ) );

But this triggers a ReplaceHandlerException at
RequestHandlerStack.replaceAll() as at that time
RequestHandlerStack.requestHandlers is not empty.

This actually looks weird to me as I'd expect a
'replaceAll' method to replace what is already
there. Maybe a bug here?

Cheers,

M'bert

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
No violence, gentlemen -- no violence, I beg of you! Consider the furniture!
           -- Sherlock Holmes

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

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

You can use requestCycle.replaceAllRequestHandlers(new
ResourceRequestHandler(new ByteArrayResource(byteArray))) in your page code.
This will stop the page rendering and will return the byte[] from this
response. You can still configure the ByteArrayResource - filename,
disposition, etc.


On Tue, Feb 19, 2013 at 10:23 AM, Martin Dietze <di...@fh-wedel.de> wrote:

> On Mon, February 18, 2013, Carl-Eric Menzel wrote:
>
> > For generating binaries, I would *really* recommend doing this change.
> > Pages simply are not a good fit for that. Also, it shouldn't be that
> > big of a change, since you're writing to the Response anyway. Within
> > AbstractResource's WriteCallback you're going to use the same Response
> > object, so you can simply copy most of your code over without much
> > change.
>
> IMO the problem is not that much how the response is generated,
> but how the component is already uses within the system. At
> this point creating a download link is simple as it simply is a
> BookmarkableLink to that page with the appropriate page
> parameters. Consequently, the download links are bookmarkable.
> I simply don't know whether any of our users depend on that
> feature. And, apart from that, porting a productive system from
> 1.4.x to 6.6.0 I still expect quite a few more issues, thus I'd
> prefer not to touch code that works.
>
> That brings me back to my question to the developers - are the
> problems I described in my original post 'by design', or would
> at least moving the adding of markup from the end of
> Page.onAfterRender() to an overridable method be a realistic
> option?
>
> Cheers,
>
> M'bert
>
> --
> ----------- / http://herbert.the-little-red-haired-girl.org /
> -------------
> =+=
> Eine Hund hat Herrchen und Frauchen..., eine Katze hat Personal!
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>


-- 
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com <http://jweekend.com/>

Re: Migration issue: page that writes binary data to the response

Posted by Martin Dietze <di...@fh-wedel.de>.
On Mon, February 18, 2013, Carl-Eric Menzel wrote:

> For generating binaries, I would *really* recommend doing this change.
> Pages simply are not a good fit for that. Also, it shouldn't be that
> big of a change, since you're writing to the Response anyway. Within
> AbstractResource's WriteCallback you're going to use the same Response
> object, so you can simply copy most of your code over without much
> change.

IMO the problem is not that much how the response is generated,
but how the component is already uses within the system. At
this point creating a download link is simple as it simply is a
BookmarkableLink to that page with the appropriate page
parameters. Consequently, the download links are bookmarkable. 
I simply don't know whether any of our users depend on that
feature. And, apart from that, porting a productive system from
1.4.x to 6.6.0 I still expect quite a few more issues, thus I'd
prefer not to touch code that works.

That brings me back to my question to the developers - are the
problems I described in my original post 'by design', or would
at least moving the adding of markup from the end of
Page.onAfterRender() to an overridable method be a realistic
option?

Cheers,

M'bert

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
Eine Hund hat Herrchen und Frauchen..., eine Katze hat Personal!

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

Posted by Carl-Eric Menzel <cm...@wicketbuch.de>.
On Mon, 18 Feb 2013 19:03:41 +0100
Martin Dietze <di...@fh-wedel.de> wrote:

> On Mon, February 18, 2013, Carl-Eric Menzel wrote:
> 
> > Is there a particular reason you're using a page?
> 
> One - unfortunately - big reason: it's legacy code (most of
> which I did not even write myself). The Wicket upgrade is badly
> needed for browser compatibiy, however I don't want to change
> code if it's not absolutely necessary. 

For generating binaries, I would *really* recommend doing this change.
Pages simply are not a good fit for that. Also, it shouldn't be that
big of a change, since you're writing to the Response anyway. Within
AbstractResource's WriteCallback you're going to use the same Response
object, so you can simply copy most of your code over without much
change.

(pseudocode from memory, but close enough)

MyResource extends AbstractResource {
 @Override newResourceResponse(Attributes att) {
  att.setFilename("foo.pdf");
  att.disableCaching();
  att.setContentType("text/pdf");
  att.setWriteCallback(new WriteCallback() {
    @Override writeData(Attributes att) {
      Response r = att.getResponse();
      // write to the response here like you did before
    }
  });
 }
}

Except in this case you won't have to mangle the Response object like
you have to do with the page.

Carl-Eric


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

Posted by Martin Dietze <di...@fh-wedel.de>.
On Mon, February 18, 2013, Carl-Eric Menzel wrote:

> Is there a particular reason you're using a page?

One - unfortunately - big reason: it's legacy code (most of
which I did not even write myself). The Wicket upgrade is badly
needed for browser compatibiy, however I don't want to change
code if it's not absolutely necessary. 

Cheers,

M'bert

-- 
----------- / http://herbert.the-little-red-haired-girl.org / -------------
=+= 
Man moechte ja lieber Auslaender sein als gieriges kleines Inlaenderschwein,
doch wo das eine nicht geht, da faengt das andere an, und das Problem ist,
dass man wo man ist nichts anderes sein kann...

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Migration issue: page that writes binary data to the response

Posted by Carl-Eric Menzel <cm...@wicketbuch.de>.
I would simply do this in a Resource (e.g. subclass AbstractResource)
rather than in a page. Resources are for binary data, Pages are for
markup. That way you don't have to mess around in any way with the
response or anything like that.

Is there a particular reason you're using a page?

Carl-Eric

On Mon, 18 Feb 2013 17:55:37 +0100
Martin Dietze <di...@fh-wedel.de> wrote:

> In the project I'm currently porting from 1.4.x to 6.6.0 I've
> run into an issue with Wicket pages which stream binary data
> into the WebResponse (e.g. ZIP archives created on the fly).
> 
> First thing I found was that obviously I *have* to create
> templates for these pages even though they are not going to be
> used for anything. 
> 
> The second thing is more serious: when writing to the response I
> get an IllegalStateException as the template code has already
> been written to it. This can be circumvented by calling
> Response.reset() before Response.write() in my code. However in
> development mode I still get an ISE as in Page.onAfterRender()
> there's this code here:
> 
> | if
> (getApplication().getDebugSettings().isOutputMarkupContainerClassName())
> | { |     String className = Classes.name(getClass());
> |     getResponse().write("<!-- Page Class ");
> |     getResponse().write(className);
> |     getResponse().write(" END -->\n");
> | }
>                                                                                                                                                 }
> Now of course I can write:
> 
> | @Override
> | protected void onAfterRender() {
> |   try { super.onAfterRender(); } catch (IllegalStateException e) { }
> | }
> 
> ... but I guess we agree that while this works it is far from nice.
> 
> I am not sure if I understand correctly what the above code is
> trying to tell me. Does it mean that I am simply not supposed to
> deliver my ZIP files by a Wicket page that way? 
> 
> If with today's Wicket version there's a different or even better
> way to do this, which one would that be?
> 
> Else, would there be any harm in making the Page class more
> friendly to this kind of use, by e.g. putting the above
> if-statement into an overridable method and adding an option to
> the Component class to tell it that there's no markup for it and
> it should simply not expect any?
> 
> Cheers,
> 
> M'bert
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org