1

私が取り組んでいるプロジェクトでは、Wicket1.4から1.5にアップグレードしたいと考えています。いくつかの作業の後、ほとんどのことが正常に機能するようになりました。

ただし、1つの主要なことがまだ機能していません。古いJSP/サーブレットを新しいWicketベースのアプリケーションにラップする必要があり、古い1.4アプローチは機能しなくなりました。

1.4での簡略化されたhtml出力

<body>
    <div id="container">
        wrappedContentFromJsp
    </div>  
<body>

1.5での簡略化されたhtml出力

<body>
    wrappedContentFromJsp   
    <div id="container">        
    </div>  
<body>

したがって、すべてのJSPコンテンツは、ラップしたいタグの外側にレンダリングされます。

ラッピングの魔法は、内部AbstractServletWrapperPanelWebMarkupContainer.onRender(MarkupStream markupStream)オーバーライドで発生します。ただし、Wicket 1.5では、提供されなくなったため、呼び出すことができませmarkupStream.next()。私はまだこれを回避する方法を見つけていません。

参照としてサンプルパネル実装を使用した1.4の作業コード:

public abstract class AbstractServletWrapperPanel extends Panel {

    public AbstractServletWrapperPanel(String id, final  String servletName, String tagId) {
        super(id);
        add(new WebMarkupContainer(tagId) {

            @Override
            protected void onRender(MarkupStream markupStream) {
                markupStream.next();
                try {
                    WebRequestCycle cycle = (WebRequestCycle) RequestCycle.get();
                    ServletRequest request = cycle.getWebRequest().getHttpServletRequest();
                    ServletResponse response = cycle.getWebResponse().getHttpServletResponse();
                    ServletContext context = ((WebApplication) Application.get()).getServletContext();
                    RequestDispatcher rd = context.getNamedDispatcher(servletName);
                    if (rd != null) {
                        rd.include(request, response);
                    } else {
                        // handling...
                    }
                } catch (Exception e) {
                    // handling...
                }
            }
        });
    }
}

//Impl
public class WrapperPanel extends AbstractServletWrapperPanel {
    private static final long serialVersionUID = 1L;

    public WrapperPanel(String id, final String servletName) {
        super(id, servletName, "wrappedContentId");
    }   
}

//WrapperPanel html
<body>
    <wicket:panel>
        <wicket:container wicket:id="wrappedContentId"/>
    </wicket:panel>
</body>

(HttpServletRequest)RequestCycle.get().getRequest().getContainerRequest()1.5バージョンでは、とを介してリクエストとレスポンスを取得しています(HttpServletResponse)RequestCycle.get().getResponse().getContainerResponse()

それから私はしようとしました:

  • onRender()を使用する-1.5ではmarkupStream.next()提供されなくなった 魔法
  • に移動しますonComponentTagBody(MarkupStream markupStream, ComponentTag tag)
    • 注:onComponentTagBody()を呼び出すには、wicket:containerタグを開く必要がありました<wicket:container wicket:id="wrappedContentId"></wicket:container>。また、呼び出される直前にmarkupStream.next()そのステップが実行されるため、呼び出さずに試しました。Component.internalRenderComponent()onComponentTagBody
  • に移動しますonComponentTag(ComponentTag tag)
  • 上記の設定と組み合わせsetRenderBodyOnly(true)WebMarkupContatiner.onInitialize()
  • <div>の代わりにタグを使用するwicket:container
  • 1.5のレンダリングプロセスを追跡するには、デバッグモードを使用します。しかし、それでも、コンポーネントをレンダリングする新しい1.5の方法の重要な部分を見逃していると思います。

すぐにすべてのJSP機能をWicketに移行するオプションはないので、これは現時点で私たちにとって一種の目玉です。

参考までに、これを行う1.4の方法は、記事jsp-and-wicket-sitting-in-a-treeおよびWicketwikiで見つけたアプローチとよく似ています。

この問題を解決するための助けをいただければ幸いです。

[編集]
TheStijnからの提案の後、私も呼び出しを試みましgetAssociatedMarkupStream()onRender()が、次のエラーが発生します。org.apache.wicket.markup.MarkupNotFoundException: Markup of type 'html' for component '... AbstractServletWrapperPanel$1' not found.

4

2 に答える 2

1

マーティン・グリゴロフからの多大な助けと指針の後で、私はこれに対する解決策を見つけました。そこにたどり着くプロセスをたどるには、ユーザーのフォーラムを見てください。

以下は、それを機能させるための生の出力にすぎないことに注意してください。それを「パッケージ化」するためのより良い方法があるかもしれません。だからそれが何であるかを考えてみてください。

//Stripped code for clarity

@Override
public void onComponentTagBody(MarkupStream markupStream, ComponentTag tag) {

 //Set up mock response and dispatch.   
 ServletContext context = WebApplication.get().getServletContext(); 
 ServletRequest request = (HttpServletRequest)RequestCycle.get().getRequest().getContainerRequest();
 MockResponse mockResponse = new MockResponse((HttpServletResponse)RequestCycle.get().getResponse().getContainerResponse());
 RequestDispatcher rd = context.getNamedDispatcher(aServletName);
 rd.include(request, mockResponse);

 //As in Wicket's Include.onComponentTagBody(MarkupStream markupStream, ComponentTag tag)
 replaceComponentTagBody(markupStream, tag, mockResponse.getOutput());
}


private static class MockResponse extends HttpServletResponseWrapper {    
 ServletOutputStream servletStream;
 ByteArrayOutputStream byteStream;

 public MockResponse(HttpServletResponse response) {
  super(response);      
  byteStream = new ByteArrayOutputStream();
  servletStream = new ServletOutputStream() {

    @Override
    public void write(int b) {
       byteStream.write(b);
     }
   };
 }

 @Override
 public ServletOutputStream getOutputStream() {
  return servletStream;
 }

 public String getOutput() {
    //NOTE: Remember to clean up IO in real usage...
    return byteStream.toString("UTF-8"); //Provide desired encoding
  }  
}

では、なぜ私はorg.apache.wicket.protocol.http.mockMockHttpServletResponse代わりに使用しなかったのですか?何らかの理由でどちらも呼び出されなかったgetWriter()か、呼び出されませんでしgetOutputStream()たが、後で詳しく調べる可能性があります。

于 2012-02-23T16:01:45.097 に答える
1

以前はこれを使用していませんが、を返す(Web)MarkupContainerメソッドがあります。これでうまくいくはずです。getAssociatedMarkupStreamMarkupStream

1.5移行ガイドに記載されていますが、あまりよくありません。

同じトピックについて:onRender(MarkupStream)がonRender();に変更されました。これ以上MarkupStreamはありません。getMarkupStream()を介してrender()を呼び出すと、すべてのコンポーネントを取得できます。

https://cwiki.apache.org/WICKET/migration-to-wicket-15.html#MigrationtoWicket1.5-Componentrendering

于 2012-02-13T13:11:32.057 に答える