2009-10-03 12 views
6

短い質問: Wicketを使用して表示ページにコンポーネントを追加することなく(NonCachingImageを使用するなど)、データベースから取得した動的イメージをURLに変換する必要があります。Wicket Dynamic Image URL

他のフレームワークで実装した完璧なソリューションは、イメージIDをURLパラメータとして使用し、イメージをレスポンスストリームにレンダリングするページを作成するだけです。残念ながらWicketのPageクラスは、MarkupStreamを中心にしているMarkupContainerを拡張しています。 MarkupStreamはバイトデータを直接描画するのにはあまり役に立ちません。

長い質問: 私はTomcat 6.0.18で動作するWicket 1.4.0を使用しています。イメージはPostgresデータベースに保存され、JDBC経由で取得されます。イメージは、イメージURLのみを受け入れる第三者のAPIによってレンダリングする必要があります。私は、バイトデータ、MIMEタイプ、およびDBからモデルを引き出してそれを応答ストリームに追加できるリソースオブジェクトを含むモデルオブジェクトを持っています。

アイデア?

答えて

19

自分自身でWicketを使い始めたばかりですが、リソースを独自のURLで共有リソースとしてマウントするだけです。あなたは自分のApplicationinit()をオーバーライドし、その後

getSharedResources().add(resourceKey, dynamicImageResource); 

でリソースを登録するには、私はまだ完全に、あなたが持って把握していないことを、いくつかの理由

mountSharedResource(path, resourceKey); 

で共有リソースとしてマウントmountSharedResource()に渡すリソースキーにアプリケーションのクラス名を付加します。


いくつかのボーナス投票に完全な実例を追加してみましょう。まず加えることによりWicketApplicationinit()メソッドをオーバーライドし、その後

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

で空Wicketのテンプレートを作成します。

@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リソースは、ちょうど黒の背景にクエリパラメータを書き込みます。もちろん、DBにアクセスしたり、好きなように画像データを作成することができます。

最後にmvn jetty:runを実行すると、this URLのリソースにアクセスできます。ここで

+0

これを補う:クラスと 'getSharedResources()。putClassAlias(ListInitializer.class、" list ");を実装するIInitializerを使用します。新しいListInitializer()。init(this); 'あなたはイメージURLのクラスパス全体を前に乗り越えることができるはずです。 – Tim

+0

詳細情報を提供できますか、ティム?私はWicketで 'ListInitializer'クラスを見つけることができず、' putClassAlias'の利用可能なドキュメントは役に立ちません。 – janko

+0

ListInitializerは私の実装です。自分の例を自分の答えに展開します。 – Tim

1

は、識別子の動的にコンパイルリストについては、同じことを私の例の静的URLに共有リソースとしてセットアップ務め..

​​

とDBNAME_SUBSELECTION1(2 /などのリソースを登録し、私のListInitializer 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); 
    } 
} 

すみませんが、私は、私はもうこれを設定するために使用チュートリアルを見つけるように見えることはできませんが、これは上記の例に関連して調整することができますどのように、それは明らかです画像のために同じことをするために..(疎な説明のために申し訳ありません、もし私が私の答えを編集することができます)

+0

説明がありません。 – Tim

2

マーティン・グリゴロフがwicketinactionで本当に素敵なblogpostを書いたと言う別の答えを追加します。Wicketの1.5で、データベースからロードされた画像をアップ奉仕する方法を詳細にCOM:

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

これは、@マイケルの質問と正確に一致します。