Wicket 1.5 и JSP / сервлет - PullRequest
       17

Wicket 1.5 и JSP / сервлет

1 голос
/ 13 февраля 2012

В нашем проекте мы хотим обновить Wicket 1.4 до 1.5. После некоторой работы у нас все работает нормально.

Однако одна важная вещь еще не работает. Необходимо обернуть старые JSP / сервлеты в новое приложение на основе Wicket, и старый 1.4-подход больше не работает.

Упрощенный вывод html в 1.4

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

Упрощенный вывод html в 1.5

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

Итак, все содержимое JSP отображается вне тега, который мы хотели бы обернуть в .

Магия обертывания происходит в нашем внутреннем AbstractServletWrapperPanel и WebMarkupContainer.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>

В версии 1.5 я получаю запрос и ответ через (HttpServletRequest)RequestCycle.get().getRequest().getContainerRequest() и (HttpServletResponse)RequestCycle.get().getResponse().getContainerResponse()

Тогда я попытался:

  • используйте onRender () - магия без markupStream.next(), которая больше не предоставляется в 1.5
  • переместите его на 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-сидя-в-дереве и в Wiki wiki

Любая помощь в решении этой проблемы будет принята с благодарностью!

[EDIT]
После предложения от TheStijn я также попытался вызвать getAssociatedMarkupStream() из onRender(), но возникает следующая ошибка: org.apache.wicket.markup.MarkupNotFoundException: Markup of type 'html' for component '... AbstractServletWrapperPanel$1' not found.

Ответы [ 2 ]

1 голос
/ 23 февраля 2012

После большой помощи и указаний от Мартина Григорова я нашел решение этой проблемы. Чтобы проследить за тем, как туда добраться, хава загляните на форум пользователя

Пожалуйста, обратите внимание, что следующее - это всего лишь исходная попытка заставить его работать вообще, может быть есть более хороший способ "упаковать" его. Так что прими это за то, что есть.

//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() не были вызваны, но я мог бы рассмотреть это позже.

1 голос
/ 13 февраля 2012

Раньше это не использовалось, но у (Web)MarkupContainer есть метод getAssociatedMarkupStream, который возвращает MarkupStream, это должно работать для вас.

Это упоминается в руководстве по миграции 1.5, но не очень хорошо:

По той же теме: onRender (MarkupStream) был изменен на OnRender (); больше нет MarkupStream. Вы можете получить для каждого компонента один раз Вы вызвали render () через getMarkupStream ().

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

...