hmm... this really is a bit harder than it ought to be. 

below is a url encoding strategy and a sub-classable auto-mounting resource
that makes this a lot easier.  you can modify to suit your needs.

the use case looks like:

        // This dynamically rendered resource will auto-mount itself using the 
path
and resource name given
        private static final MountedDynamicImageResource redbox = new
MountedDynamicImageResource(
                        "/images/redbox", "redbox", 100, 100) {

                private static final long serialVersionUID = 
1021758684732149991L;

                @Override
                protected boolean render(Graphics2D graphics) {
                        graphics.setColor(Color.RED);
                        graphics.fillRect(0, 0, getWidth(), getHeight());
                        return true;
                }
        };

        MyPage() {
                add(redbox.getImage());
        }

the code for MountedDynamicImageResource looks like:

import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.Map;

import org.apache.wicket.ResourceReference;
import org.apache.wicket.markup.html.image.Image;
import
org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource;
import org.apache.wicket.protocol.http.WebApplication;

public abstract class MountedDynamicImageResource extends
                RenderedDynamicImageResource {

        private static final long serialVersionUID = -9117628603222075688L;

        private static final Map<Class<? extends MountedDynamicImageResource>,
Boolean> mounted = new HashMap<Class<? extends MountedDynamicImageResource>,
Boolean>();

        private final String name;

        public MountedDynamicImageResource(final String path, final String name,
                        int width, int height) {
                this(path, name, width, height, "png");
        }

        public MountedDynamicImageResource(final String path, final String name,
                        int width, int height, String format) {
                super(width, height, format);
                this.name = name;
                synchronized (mounted) {
                        if (mounted.get(getClass()) == null) {
                                mounted.put(getClass(), Boolean.TRUE);
                                
WebApplication.get().getSharedResources().add(getClass(), name,
                                                getLocale(), null, this);
                                WebApplication.get().mount(
                                                new 
MountedResourceRequestTargetUrlCodingStrategy(path
                                                                + "." + format, 
getClass(), name));
                        }
                }
        }

        public Image getImage() {
                return new Image(name, new ResourceReference(getClass(), name));
        }

        /**
         * {...@inheritdoc}
         */
        @Override
        protected abstract boolean render(Graphics2D graphics);
}

and the url coding strategy:

import org.apache.wicket.IRequestTarget;
import org.apache.wicket.request.RequestParameters;
import
org.apache.wicket.request.target.coding.AbstractRequestTargetUrlCodingStrategy;
import
org.apache.wicket.request.target.resource.ISharedResourceRequestTarget;
import
org.apache.wicket.request.target.resource.SharedResourceRequestTarget;

public class MountedResourceRequestTargetUrlCodingStrategy extends
                AbstractRequestTargetUrlCodingStrategy {

        private String keyPrefix;

        public MountedResourceRequestTargetUrlCodingStrategy(String mountPath,
                        Class<?> scope) {
                this(mountPath, scope, mountPath.substring(1));
        }

        public MountedResourceRequestTargetUrlCodingStrategy(String mountPath,
                        Class<?> scope, String namePrefix) {
                super(mountPath);
                this.keyPrefix = scope.getName() + "/" + namePrefix;
        }

        public IRequestTarget decode(RequestParameters requestParameters) {
                String name = requestParameters.getPath().substring(
                                getMountPath().length());
                requestParameters.setResourceKey(keyPrefix + name);
                return new SharedResourceRequestTarget(requestParameters);
        }

        public CharSequence encode(IRequestTarget requestTarget) {
                String key = ((ISharedResourceRequestTarget) requestTarget)
                                .getResourceKey();
                return getMountPath() + key.substring(keyPrefix.length());

        }

        public boolean matches(IRequestTarget requestTarget) {
                if (!(requestTarget instanceof ISharedResourceRequestTarget))
                        return false;
                String key = ((ISharedResourceRequestTarget) requestTarget)
                                .getResourceKey();
                return key.startsWith(keyPrefix);
        }
}

merry xmas!


smallufo wrote:
> 
> Hi
> 
> I hope I can use wicket to serve image data.
> I know I can extend org.apache.wicket.markup.html.image.Image and provide
> a
> DynamicImageResource
> but the generated image link is
> http://localhost/app/?wicket:interface=:0:customImage::IResourceListener::
> The image data is stored in the session and not bookmarkable, which is not
> what I want.
> 
> 
> I then created an ImagePage extends WebPage and override onBeforeRender() 
> ,
> and coding below :
> HttpServletResponse response = ((WebResponse)
> getWebRequestCycle().getResponse()).getHttpServletResponse();
>     try
>     {
>       response.setContentType("image/png");
> 
>       OutputStream responseOutputStream = response.getOutputStream();
> 
>       responseOutputStream.write(myImageBytes);
>       responseOutputStream.flush();
>       responseOutputStream.close();
>     }
>     catch (IOException e)
>     {
>       e.printStackTrace();
>     }
> 
> It works !!! And I can bookmark the image.
> 
> But there are warning output :
> 
> 2008-12-26 02:20:42,919 ERROR wicket.RequestCycle -
> org.apache.wicket.Component has not been properly rendered. Something in
> the
> hierarchy of foo.bar.ImagePage has not called super.onBeforeRender() in
> the
> override of onBeforeRender() method
> java.lang.IllegalStateException: org.apache.wicket.Component has not been
> properly rendered. Something in the hierarchy of foo.bar.ImagePage has not
> called super.onBeforeRender() in the override of onBeforeRender() method
>         at
> org.apache.wicket.Component.internalBeforeRender(Component.java:1006)
>         at org.apache.wicket.Component.beforeRender(Component.java:1034)
>         at
> org.apache.wicket.Component.prepareForRender(Component.java:2160)
> 
> Is this the "standard" way of outputing binary data ?
> If not , what is the better way  (wicket 1.3.5) ?
> 
> thanks.
> 
> 

-- 
View this message in context: 
http://www.nabble.com/WebPage-for-serving-binary-image-data-tp21169289p21170251.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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

Reply via email to