java Wicket 动态图片网址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1512510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:50:59  来源:igfitidea点击:

Wicket Dynamic Image URL

javaimageurldynamicwicket

提问by Michael Krauklis

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.

简短问题:我需要使用 Wicket 将从数据库中提取的动态图像转换为 URL,而无需向显示页面添加组件(例如使用 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. Unfortunately Wicket's Page class extends MarkupContainer, which revolves around MarkupStreams. MarkupStreams aren't very conducive to rendering byte data directly.

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

Long question: I'm using Wicket 1.4.0, running in Tomcat 6.0.18. The image is stored in a Postgres database, retrieved via JDBC. The image needs to be rendered by a third party API that only accepts image URLs. 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.

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

Any ideas?

有任何想法吗?

回答by janko

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 Applicationand register the resource with

我自己才刚刚开始使用 Wicket,但我只是将资源作为共享资源挂载,并带有自己的 URL。你只是覆盖init()在你Application和注册与资源

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 WicketApplicationby adding:

然后,通过添加以下内容来覆盖该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);
}

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.

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

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

最后,执行mvn jetty:run,您将能够访问此 URL处的资源。

回答by Tim

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 的问题完全匹配。

回答by Tim

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)

很抱歉,我似乎再也找不到我用来设置它的教程了,但是很明显这与上面的示例有什么关系,并且可以调整为对图像执行相同的操作..(对不起稀疏解释,如果还不清楚,我可以回来编辑我的答案)