2009-10-03 5 views
6

Короткий вопрос: Мне нужно превратить динамическое изображение, вытащенное из базы данных в URL, без добавления компонента на страницу отображения (например, с помощью NonCachingImage) с использованием Wicket.Wicket Dynamic Image URL

Идеальное решение (которое я реализовал в других Framework) - это просто создать страницу, которая принимает идентификатор изображения в качестве параметра url и отображает изображение в поток ответов. К сожалению, класс страницы Wicket расширяет MarkupContainer, который вращается вокруг MarkupStreams. MarkupStreams не очень помогают напрямую передавать байтовые данные.

Длинный вопрос: Я использую Wicket 1.4.0, работающий в Tomcat 6.0.18. Изображение сохраняется в базе данных Postgres, полученной через JDBC. Изображение должно отображаться сторонним API, который принимает только URL-адреса изображений. У меня есть объект модели, содержащий байтовые данные, тип mime и объект Resource, которые могут вытащить модель из БД и добавить ее в поток ответов.

Любые идеи?

ответ

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.

+0

И в дополнение к этому: использование IInitializer, реализующего класс и 'getSharedResources(). PutClassAlias ​​(ListInitializer.class,« list »); новый ListInitializer(). init (this); 'вы должны иметь возможность обойти добавление всего пути к классам для URL-адреса изображения. – Tim

+0

Можете ли вы предоставить дополнительную информацию, Тим? Я не могу найти класс ListInitializer в Wicket, и доступная документация на 'putClassAlias' тоже не помогает. – janko

+0

ListInitializer - это только моя реализация. Я расширю свой пример в собственном ответе. – Tim

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

Мне очень жаль, но я не могу найти учебник, я использовал, чтобы установить это больше, но это должно быть ясно, как это относится к приведенному выше примеру и может быть скорректирована сделать то же самое для изображений. (Извините за редкое объяснение, если я t не понял, я мог вернуться и отредактировать мой ответ)

+0

Получено без объяснения нисходящего голосования .. поразмыслить? – Tim

2

Я добавлю еще один ответ, чтобы сказать, что Мартин Григоров написал действительно приятный блог-пост в wicketinaction.ком к деталям, как обслуживать загруженные изображения из базы данных в калиткой 1.5:

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

Это точно соответствует с @ вопросом Майкла.