Wicket动态图像URL

时间:2009-10-03 01:21:33

标签: java image url dynamic wicket

简短问题: 我需要将从数据库中提取的动态图像转换为URL,而不使用Wicket将组件添加到显示页面(例如使用NonCachingImage)。

完美的解决方案(我在其他框架中实现)只是创建一个页面,将图像ID作为url参数并将图像呈现给响应流。不幸的是,Wicket的Page类扩展了MarkupContainer,它围绕着MarkupStreams。 MarkupStreams不太直接有助于渲染字节数据。

长问题: 我正在使用Wicket 1.4.0,在Tomcat 6.0.18中运行。该图像存储在Postgres数据库中,通过JDBC检索。图像需要由仅接受图像URL的第三方API呈现。我有一个模型对象,其中包含字节数据,mime类型和Resource对象,可以从DB中提取模型并将其添加到响应流中。

有什么想法吗?

3 个答案:

答案 0 :(得分:19)

我自己刚刚开始与Wicket合作,但我只是将资源作为共享资源安装,并使用自己的URL。您只需覆盖init()中的Application,然后使用

注册资源
getSharedResources().add(resourceKey, dynamicImageResource);

然后,使用

将其作为共享资源挂载
mountSharedResource(path, resourceKey);

出于某种原因,我仍然没有完全掌握,您必须将应用程序的类名添加到传递给mountSharedResource()的资源键。


让我们为一些奖金投票添加一个完整的工作示例!首先使用

创建一个空的Wicket模板
mvn archetype:create -DarchetypeGroupId=org.apache.wicket \
    -DarchetypeArtifactId=wicket-archetype-quickstart \
    -DarchetypeVersion=1.4.0 -DgroupId=com.mycompany \
    -DartifactId=myproject

然后,通过添加:

覆盖init()中的WicketApplication方法
@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);
}

小动态PNG资源只是在黑色背景上写入查询参数。当然,您可以访问您的数据库或做任何您喜欢的事情来生成图像数据。

最后,执行mvn jetty:run,您就可以在this URL访问该资源。

答案 1 :(得分:2)

我会再添加一个答案,说Martin Grigorov在wicketinaction.com上写了一篇非常好的博客文章,详细说明了如何在Wicket 1.5中提供从数据库加载的图像:

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

这与@ Michael的问题完全一致。

答案 2 :(得分:1)

这是我的示例,它对动态编译的标识符列表执行相同操作,作为具有静态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);
    }

我的ListInitializer将资源注册为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);
    }
}

我很抱歉,但我似乎找不到我以前用来设置它的教程,但应该明白这与上面的例子有什么关系,并且可以调整为图像做同样的事情。(很抱歉稀疏的解释,如果仍然不清楚我可以回来编辑我的答案)