【问题标题】:Wicket Dynamic Image URL检票口动态图片网址
【发布时间】:2010-12-03 12:10:09
【问题描述】:

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

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

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

有什么想法吗?

【问题讨论】:

    标签: java image url dynamic wicket


    【解决方案1】:

    我自己才刚刚开始使用 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
    

    然后,通过添加以下内容覆盖WicketApplication 中的init() 方法:

    @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的资源了。

    【讨论】:

    • 作为补充:使用 IInitializer 实现类和 getSharedResources().putClassAlias(ListInitializer.class, "list"); new ListInitializer().init(this);,您应该能够绕过为您的图像 url 预先设置整个类路径。
    • 你能提供更多信息吗,蒂姆?我在 Wicket 中找不到 ListInitializer 类,putClassAlias 上的可用文档也没有帮助。
    • ListInitializer 只是我的实现。我会将我的示例扩展为自己的答案。
    • 啊,太棒了。我缺少的部分是资源上的 getParameter;我完全忽略了这一点。我正在寻找它通过构造函数传递,就像在页面模型中一样。谢谢扬科!
    • 关于提供给测试的 URL 的注释:localhost:8080/myproject/resource/org.apache.wicket.Application/… 实际上 /resource 下的任何内容都可以,例如:localhost:8080/myproject/resource?id=someId
    【解决方案2】:

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

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

    这与@Michael 的问题完全吻合。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多