Wicket 1.5 和 JSP/servlet 包装
在我正在进行的项目中,我们希望从 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()
和 < code>(HttpServletResponse)RequestCycle.get().getResponse().getContainerResponse()
然后我尝试:
- 使用 onRender()-magic 而无需1.5 中不再提供的
markupStream.next()
- 将其移至
onComponentTagBody(MarkupStream markupStream, ComponentTag tag)
- 注意:要调用 onComponentTagBody(),我必须打开 wicket:container 标签
。我还尝试不调用markupStream.next()
,因为该步骤是在调用onComponentTagBody
之前在Component.internalRenderComponent()
中执行的。
- 注意:要调用 onComponentTagBody(),我必须打开 wicket:container 标签
- 将其移动到上面结合的
onComponentTag(ComponentTag tag)
- 并在
WebMarkupContatiner.onInitialize()
中设置setRenderBodyOnly(true)
- 使用
< ;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:未找到组件“... AbstractServletWrapperPanel$1”的“html”类型标记。
In the project I'm on we want to upgrade from Wicket 1.4 to 1.5. After some work we got most things working OK.
However one major thing is not working yet. There's a need to wrap old JSP/servlets into the new Wicket based application and the old 1.4-approach is not working anymore.
Simplified html output in 1.4
<body>
<div id="container">
wrappedContentFromJsp
</div>
<body>
Simplified html output in 1.5
<body>
wrappedContentFromJsp
<div id="container">
</div>
<body>
So, all the JSP content renders outside the tag that we like to wrap it in.
The wrapping magic happens in our internal AbstractServletWrapperPanel
and the WebMarkupContainer.onRender(MarkupStream markupStream)
override. However, in Wicket 1.5 we can't invoke markupStream.next()
since it's no longer provided. I have not found a way around this yet.
Working code for 1.4 with a sample panel implementation as reference:
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>
In the 1.5 version I'm getting the request and response via (HttpServletRequest)RequestCycle.get().getRequest().getContainerRequest()
and (HttpServletResponse)RequestCycle.get().getResponse().getContainerResponse()
Then I've tried to:
- use the onRender()-magic without
markupStream.next()
that's no longer provided in 1.5 - move it to
onComponentTagBody(MarkupStream markupStream, ComponentTag tag)
- Note: To invoke onComponentTagBody() I had to open up the wicket:container tag
<wicket:container wicket:id="wrappedContentId"></wicket:container>
. I also tried without invokingmarkupStream.next()
as that step is performed inComponent.internalRenderComponent()
just beforeonComponentTagBody
is invoked at all.
- Note: To invoke onComponentTagBody() I had to open up the wicket:container tag
- move it to
onComponentTag(ComponentTag tag)
- combined above with setting
setRenderBodyOnly(true)
in theWebMarkupContatiner.onInitialize()
- use a
<div>
tag instead of awicket:container
- use debug mode to track down the rendering process of 1.5. But still, I guess I'm missing out some key part of the new 1.5 way of rendering components.
Since it's not an option to migrate all that JSP functionality to Wicket anytime soon this is kind of a showstopper for us at the moment.
For reference, the 1.4 way of doing this is much similar to the approach I found in the article jsp-and-wicket-sitting-in-a-tree and on the Wicket wiki
Any help solving this issue would be very appreciated!
[EDIT]
After a suggestion from TheStijn I've also tried invoking getAssociatedMarkupStream()
from onRender()
but that raises the following error: org.apache.wicket.markup.MarkupNotFoundException: Markup of type 'html' for component '... AbstractServletWrapperPanel$1' not found.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以前没有使用过这个,但
(Web)MarkupContainer
有一个方法getAssociatedMarkupStream
,它返回MarkupStream
,这应该适合你。1.5 迁移指南中提到了这一点,但不是很好:
https://cwiki.apache.org/WICKET /migration-to-wicket-15.html#MigrationtoWicket1.5-Componentrendering
Not used this before but
(Web)MarkupContainer
has a methodgetAssociatedMarkupStream
which returns theMarkupStream
, this should work for you.It is mentioned in the 1.5 migration guide but not very well:
https://cwiki.apache.org/WICKET/migration-to-wicket-15.html#MigrationtoWicket1.5-Componentrendering
在马丁·格里戈罗夫的大力帮助和指导下,我找到了解决方案。要了解到达那里的过程,请查看 用户论坛
请注意,以下只是尝试使其正常工作的原始输出,可能有一些更好的“打包”方法 它。所以就接受它的本来面目吧。
那么为什么我不使用 org.apache.wicket.protocol.http.mockMockHttpServletResponse 来代替呢?
由于某种原因,
getWriter()
或getOutputStream()
都没有被调用,但我稍后可能会进一步研究。After great help and pointers from Martin Grigorov I found the solution to this. To follow the process of getting there, hava look at the user's forum
Please note that following is just the raw output of trying to get it to work at all, there might be some nicer way to "package" it. So take it for what it is.
So why didn't I use
org.apache.wicket.protocol.http.mockMockHttpServletResponse
instead?For some reason neither
getWriter()
orgetOutputStream()
got invoked, but I might look further into that later.