简短问题: 我需要将从数据库中提取的动态图像转换为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中提取模型并将其添加到响应流中。
有什么想法吗?
答案 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);
}
}
我很抱歉,但我似乎找不到我以前用来设置它的教程,但应该明白这与上面的例子有什么关系,并且可以调整为图像做同样的事情。(很抱歉稀疏的解释,如果仍然不清楚我可以回来编辑我的答案)