【发布时间】:2012-02-13 08:52:18
【问题描述】:
在我正在进行的项目中,我们希望从 Wicket 1.4 升级到 1.5。经过一些工作,我们得到了大部分工作正常。
但是,一件主要的事情还没有奏效。需要将旧的 JSP/servlet 包装到基于 Wicket 的新应用程序中,而旧的 1.4 方法不再适用。
1.4 中简化的 html 输出
<body>
<div id="container">
wrappedContentFromJsp
</div>
<body>
1.5 中简化的 html 输出
<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() 获得请求和响应
然后我尝试:
- 使用 1.5 中不再提供的不带
markupStream.next()的 onRender()-magic - 将其移至
onComponentTagBody(MarkupStream markupStream, ComponentTag tag)- 注意:要调用 onComponentTagBody(),我必须打开 wicket:container 标签
<wicket:container wicket:id="wrappedContentId"></wicket:container>。我也尝试不调用markupStream.next(),因为该步骤是在Component.internalRenderComponent()中执行的,就在onComponentTagBody被调用之前。
- 注意:要调用 onComponentTagBody(),我必须打开 wicket:container 标签
- 将其移至
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 和 Wicket wiki 上找到的方法非常相似
任何解决此问题的帮助将不胜感激!
[编辑]
根据 TheStijn 的建议,我也尝试从 onRender() 调用 getAssociatedMarkupStream() 但这会引发以下错误:org.apache.wicket.markup.MarkupNotFoundException: Markup of type 'html' for component '... AbstractServletWrapperPanel$1' not found.
【问题讨论】:
标签: jsp servlets wicket wicket-1.5 requestdispatcher