简体   繁体   English

Wicket动态图像URL

[英]Wicket Dynamic Image URL

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 Wicket. 简短的问题:我需要将从数据库中提取的动态图像转换为URL,而无需使用Wicket向显示页面添加组件(例如使用NonCachingImage)。

The perfect solution (that I've implemented in other Frameworks) is simply to create a page that takes the image ID as a url parameter and renders the image to the response stream. 完美的解决方案(我在其他框架中实现)只是创建一个页面,将图像ID作为url参数并将图像呈现给响应流。 Unfortunately Wicket's Page class extends MarkupContainer, which revolves around MarkupStreams. 不幸的是,Wicket的Page类扩展了MarkupContainer,它围绕着MarkupStreams。 MarkupStreams aren't very conducive to rendering byte data directly. MarkupStreams不太直接有助于渲染字节数据。

Long question: I'm using Wicket 1.4.0, running in Tomcat 6.0.18. 长问题:我正在使用Wicket 1.4.0,在Tomcat 6.0.18中运行。 The image is stored in a Postgres database, retrieved via JDBC. 该图像存储在Postgres数据库中,通过JDBC检索。 The image needs to be rendered by a third party API that only accepts image URLs. 图像需要由仅接受图像URL的第三方API呈现。 I have a model object that contains the byte data, mime type, and a Resource object that can pull the model from the DB and add it to a response stream. 我有一个模型对象,其中包含字节数据,mime类型和Resource对象,可以从数据库中提取模型并将其添加到响应流。

Any ideas? 有任何想法吗?

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. 我自己刚刚开始与Wicket合作,但我只是将资源作为共享资源挂载,并使用自己的URL。 You just override init() in your Application and register the resource with 您只需覆盖Application init()并使用注册资源

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() . 出于某种原因,我仍然没有完全掌握,您必须将应用程序的类名前置到您传递给mountSharedResource()的资源键。


Let's add a fully working example for some bonus votes! 让我们为一些奖金投票添加一个完整的工作示例! First create an empty Wicket template with 首先创建一个空的Wicket模板

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: 然后,通过添加以下内容覆盖WicketApplicationinit()方法:

@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. 小动态PNG资源只是在黑色背景上写入查询参数。 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 . 最后,执行mvn jetty:run ,您将能够访问此URL的资源。

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: 我将添加另一个答案,说Martin Grigorov在wicketinaction.com上写了一篇非常好的博文,详细介绍了如何在Wicket 1.5中提供从数据库加载的图像:

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

This matches exactly with @Michael's question. 这与@ Michael的问题完全一致。

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

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) 对不起,我似乎无法找到我以前用来设置它的教程,但应该明白这与上面的例子有什么关系,并且可以调整为图像做同样的事情..(对不起稀疏的解释,如果还不清楚我可以回来编辑我的答案)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM