Dynamic Gateway URL

Short question: I need to turn a dynamic image pulled from a database into a URL without adding a component to the display page (for example, using NonCachingImage) using Wicket.

The ideal solution (which I implemented in other Framework) is to simply create a page that accepts the image identifier as a url parameter and displays the image in the response stream. Unfortunately, the Wicket Page class extends the MarkupContainer, which revolves around MarkupStreams. MarkupStreams do not really help directly transfer byte data.

Long task: I am using Wicket 1.4.0, running on Tomcat 6.0.18. The image is saved in the Postgres database obtained through JDBC. The image must be displayed by a third-party API that accepts only image URLs. I have a model object containing byte data, a mime type, and a Resource object that can pull a model from the database and add it to the response stream.

Any ideas?

+6
java url dynamic image wicket
source share
3 answers

I just started working with Wicket on my own, but I just mounted the resource as a shared resource with my own URL. You simply override init() in your Application and register the resource with

 getSharedResources().add(resourceKey, dynamicImageResource); 

Then you mount it as a share using

 mountSharedResource(path, resourceKey); 

For some reason that I still don't fully understand, you have to add the name of the application class to the resource key that you pass to mountSharedResource() .


Add a fully working example for some bonus voices! First create an empty Wicket template with

 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:

 @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 small dynamic PNG resource simply records the query parameter on a black background. Of course, you can access your database or do whatever you want to get image data.

Finally, run mvn jetty:run , and you can access the resource in this URL .

+19
source share

I will add another answer to say that Martin Grigorov wrote a really good blog post on wicketinaction.com to describe in detail how to service images downloaded from the database in Wicket 1.5:

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

This corresponds to the exact assignment of @Michael.

+2
source share

Here's my example, which does the same for a dynamically compiled list of identifiers, served as a shared resource with a static 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, which registers resources as 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); } } 

Sorry, but I can’t find the tutorial that I used to configure it, but it should be obvious how this relates to the above example and can be adjusted to do the same for the images .. (Sorry for the rare explanation, if it is still unclear, I could go back and edit my answer)

+1
source share

All Articles