Wicket Dynamic Image URL

后端 未结 3 1855
耶瑟儿~
耶瑟儿~ 2020-12-14 14:11

Short question: I need to turn a dynamic image pulled from a database into a URL without adding a component to the displaying page (such as using a NonCachingImage) using Wi

相关标签:
3条回答
  • 2020-12-14 14:14

    Here's my example that does the same for a dynamically compiled list of identifiers, served up as a shared resource with a static URL..

    public class WicketApplication extends WebApplication {
        ...snip...
        @Override
        protected void init() {
            //Spring
            addComponentInstantiationListener(new SpringComponentInjector(this));
    
            //Register export lists as shared resources
            getSharedResources().putClassAlias(ListInitializer.class, "list");
            new ListInitializer().init(this);
        }
    

    And my ListInitializer that registers the resources as DBNAME_SUBSELECTION1(2/3/..)

    public class ListInitializer implements IInitializer {
        public ListInitializer() {
            InjectorHolder.getInjector().inject(this);
        }
    
        @SpringBean
        private DatabankDAO dbdao;
    
        @Override
        public void init(Application application) {
            //For each databank
            for (Databank db : dbdao.getAll()) {
                String dbname = db.getName();
                //and all collection types
                for (CollectionType ct : CollectionType.values()) {
                    //create a resource
                    Resource resource = getResource(dbname, ct);
                    //and register it with shared resources
                    application.getSharedResources().add(this.getClass(), dbname + '_' + ct, null, null, resource);
                }
            }
        }
    
        @SpringBean
        private MyApp   MyApp;
    
        public Resource getResource(final String db, final CollectionType collectionType) {
            return new WebResource() {
                @Override
                public IResourceStream getResourceStream() {
                    List<String> entries = MyApp.getEntries(db, collectionType.toString());
                    StringBuilder sb = new StringBuilder();
                    for (String entry : entries) {
                        sb.append(entry.toString());
                        sb.append('\n');
                    }
                    return new StringResourceStream(sb, "text/plain");
                }
    
                @Override
                protected void setHeaders(WebResponse response) {
                    super.setHeaders(response);
                    response.setAttachmentHeader(db + '_' + collectionType);
                }
            }.setCacheable(false);
        }
    }
    

    I'm sorry but I can't seem to find the tutorial I used to set this up anymore, but it should be evident how this relates to the above example and can be adjusted to do the same for images.. (Sorry for the sparse explanation, if it's still unclear I could come back and edit my answer)

    0 讨论(0)
  • 2020-12-14 14:24

    I'll add another answer to say Martin Grigorov wrote a really nice blogpost over at wicketinaction.com to detail how to serve up images loaded from a database in Wicket 1.5:

    http://wicketinaction.com/2011/07/wicket-1-5-mounting-resources/

    This matches exactly with @Michael's question.

    0 讨论(0)
  • 2020-12-14 14:34

    I've only just started to work with Wicket myself, but I would simply mount the resource as a shared resource with its own URL. You just override init() in your Application and register the resource with

    getSharedResources().add(resourceKey, dynamicImageResource);
    

    Then, you mount it as a shared resource with

    mountSharedResource(path, resourceKey);
    

    For some reason, that I still do not completely grasp, you have to prepend the class name of the application to the resource key you pass to mountSharedResource().


    Let's add a fully working example for some bonus votes! First create an empty Wicket template with

    mvn archetype:create -DarchetypeGroupId=org.apache.wicket \
        -DarchetypeArtifactId=wicket-archetype-quickstart \
        -DarchetypeVersion=1.4.0 -DgroupId=com.mycompany \
        -DartifactId=myproject
    

    Then, override the init() method in WicketApplication by adding:

    @Override
    protected void init() {
        final String resourceKey = "DYN_IMG_KEY";
        final String queryParm = "id";
    
        getSharedResources().add(resourceKey, new Resource() {
            @Override
            public IResourceStream getResourceStream() {
                final String query = getParameters().getString(queryParm);
    
                // generate an image containing the query argument
                final BufferedImage img = new BufferedImage(100, 100,
                        BufferedImage.TYPE_INT_RGB);
                final Graphics2D g2 = img.createGraphics();
                g2.setColor(Color.WHITE);
                g2.drawString(query, img.getWidth() / 2, img.getHeight() / 2);
    
                // return the image as a PNG stream
                return new AbstractResourceStreamWriter() {
                    public String getContentType() {
                        return "image/png";
                    }
                    public void write(OutputStream output) {
                        try { ImageIO.write(img, "png", output); }
                        catch (IOException ex) { /* never swallow exceptions! */ }
                    }
                };
            }
        });
    
        mountSharedResource("/resource", Application.class.getName() + "/" +
                resourceKey);
    }
    

    The little dynamic PNG resource just writes the query parameter on black background. Of course, you can access your DB or do whatever you like to produce the image data.

    Finally, execute mvn jetty:run, and you will be able to access the resource at this URL.

    0 讨论(0)
提交回复
热议问题