Wicket动态图像URL

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

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

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

有任何想法吗?

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

 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 

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

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

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

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

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

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

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

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