2009-10-03 7 views
6

Domanda breve: Ho bisogno di trasformare un'immagine dinamica estratta da un database in un URL senza aggiungere un componente alla pagina di visualizzazione (come l'utilizzo di NonCachingImage) tramite Wicket.Wicket Dynamic Image URL

La soluzione perfetta (che ho implementato in altri Framework) è semplicemente quella di creare una pagina che prende l'ID dell'immagine come parametro url e rende l'immagine al flusso di risposta. Sfortunatamente la classe Page di Wicket estende MarkupContainer, che ruota attorno a MarkupStreams. MarkupStreams non è molto propizio al rendering diretto dei dati di byte.

Domanda lunga: Sto utilizzando Wicket 1.4.0, in esecuzione in Tomcat 6.0.18. L'immagine è archiviata in un database Postgres, recuperato tramite JDBC. L'immagine deve essere resa da un'API di terze parti che accetta solo URL di immagini. Ho un oggetto modello che contiene i dati di byte, il tipo mime e un oggetto di risorsa che può estrarre il modello dal DB e aggiungerlo a un flusso di risposta.

Qualche idea?

risposta

19

Ho appena iniziato a lavorare con Wicket da solo, ma vorrei semplicemente montare la risorsa come risorsa condivisa con il proprio URL. Basta sovrascrivere init() nel vostro Application e registrare la risorsa con

getSharedResources().add(resourceKey, dynamicImageResource); 

Poi, si monta come una risorsa condivisa con

mountSharedResource(path, resourceKey); 

Per qualche ragione, che io ancora non completamente afferrare, avete per anteporre il nome classe dell'applicazione alla chiave della risorsa passata a mountSharedResource().


Aggiungiamo un esempio pienamente funzionante per alcuni voti bonus! In primo luogo creare un modello di Wicket vuota con

mvn archetype:create -DarchetypeGroupId=org.apache.wicket \ 
    -DarchetypeArtifactId=wicket-archetype-quickstart \ 
    -DarchetypeVersion=1.4.0 -DgroupId=com.mycompany \ 
    -DartifactId=myproject 

Poi, l'override del metodo init() in WicketApplication aggiungendo:

@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); 
} 

La piccola risorsa PNG dinamica scrive solo il parametro di query su sfondo nero. Naturalmente, puoi accedere al tuo DB o fare quello che vuoi per produrre i dati dell'immagine.

Infine, eseguire mvn jetty:run e sarà possibile accedere alla risorsa this URL.

+0

E per completare questo: Utilizzo di un IInitializer che implementa la classe e 'getSharedResources(). PutClassAlias ​​(ListInitializer.class," list "); nuovo ListInitializer(). init (this); 'dovresti essere in grado di aggirare l'intero percorso di classe per l'URL dell'immagine. – Tim

+0

Puoi fornire maggiori informazioni, Tim? Non riesco a trovare la classe 'ListInitializer' in Wicket e anche la documentazione disponibile su' putClassAlias' non è utile. – janko

+0

ListInitializer è solo la mia implementazione .. Espanderò il mio esempio in una propria risposta .. – Tim

1

Ecco il mio esempio che fa la stessa cosa per un elenco compilato in modo dinamico di identificatori, servito come una risorsa condivisa con un URL statico ..

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); 
    } 

E la mia ListInitializer che registra le risorse come 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); 
    } 
} 

mi dispiace, ma io non riesco a trovare il tutorial che ho usato per installare questo più, ma dovrebbe essere evidente come questo si riferisce all'esempio di cui sopra e può essere regolato fare lo stesso per le immagini .. (Scusa per la spiegazione sparsa, se io Non è ancora chiaro che potrei tornare e modificare la mia risposta)

+0

Ricevuto nessuna spiegazione down-vote .. cura di elaborare? – Tim