Hi,
you're absolutely right and now I got it working. Big thanks for the help!
response.getWriter() (for character content) is never invoked, but
response.getOutputStream() (for binary/character content), is.
I don't now what exactly decides the binary approach, maybe something built
into the rd.include()?
For reference our JSP files are included like this in the old servlets:
ServletContext sc = getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher("urlToJsp");
rd.include(request, response);
It might be of interest for others to know a little more about how it all
worked out (will post it on SO as well).
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.
//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
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
}
}
So why didn't I use
org.apache.wicket.protocol.http.mockMockHttpServletResponse instead?
For some reason neither getWriter() or getOutputStream() got invoked, but I
might look further into that later.
Thanks again Martin for the quick replies and pointing me in the right
direction,
Johan
2012/2/23 Martin Grigorov <[email protected]>
> On Thu, Feb 23, 2012 at 10:29 AM, Johan Isaksson <[email protected]> wrote:
> > Hi, now my mail is back on track.
> >
> > Actually I've been trying what you suggesting before but I could not get
> > any "output" from my mock response.
> > As shown below on the sysout my mock's getWriter() never gets invoked.
> > Note: I have also tried using MockHttpServletResponse with the same
> result.
> >
> > Am I missing something in how mocking a response and getting the output
> is
> > accomplished?
> >
> > public void onComponentTagBody(MarkupStream markupStream, ComponentTag
> tag)
> > {
> > ServletContext context = WebApplication.get().getServletContext();
> > ServletRequest request =
> >
> (HttpServletRequest)RequestCycle.get().getRequest().getContainerRequest();
> > ServletResponse response =
> >
> (HttpServletResponse)RequestCycle.get().getResponse().getContainerResponse();
> > MockResponse mockResponse = new MockResponse(response);
> > RequestDispatcher rd = context.getNamedDispatcher(aServletName);
> > rd.include(request, mockResponse);
> > replaceComponentTagBody(markupStream, tag, mockResponse.getOutput());
> > }
> >
> > private static class MockResponse extends HttpServletResponseWrapper {
> > private final CharArrayWriter writer = new CharArrayWriter();
> >
> > public MockResponse(HttpServletResponse response) {
> > super(response);
> > }
> >
> > @Override
> > public PrintWriter getWriter() throws IOException {
> > System.out.println(" -- GET MOCK WRITER");
> > return new PrintWriter(writer);
> > }
> >
> > public String getOutput() {
> > System.out.println(" -- GET MOCK OUTPUT");
> > return writer.toString();
> > }
> > }
> >
> > sysout only displays:
> > -- GET MOCK OUTPUT
> >
> > So no getWriter() call as it seems...
>
> This depends on how your servlet writes to the response, no ?
> But if you are sure that the servlet writes HTML then you can convert
> the byte[] back to String.
>
> >
> >
> > Thanks,
> > Johan
> >
> > 2012/2/23 Martin Grigorov <[email protected]>
> >
> >> Hi,
> >>
> >> See how Include does it and replace with your logic then.
> >> The important method is
> >> org.apache.wicket.markup.html.include.Include#onComponentTagBody()
> >> that just calls
> >> org.apache.wicket.Component#replaceComponentTagBody() with the
> >> 'content' to print. It is up to you how to load that 'content'.
> >>
> >> The code from SO:
> >> 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...
> >> }
> >>
> >> Use mocked HttpServletResponse instead that collects the written
> >> output from rc.include() and use it as 'content'.
> >>
> >> HTH
> >>
> >> On Thu, Feb 23, 2012 at 8:49 AM, Christian Rudh
> >> <[email protected]> wrote:
> >> > I'm answering for Johan (he is having mail problems):
> >> >
> >> > The Wicket Include way only seems to work for servlets that have a
> >> > mapping in web.xml so you have an URL to call? But what if you have
> >> > legacy servlets bundled in your project that have no mapping but only
> >> > the "servlet" part (and you don't want to expose them), then you have
> >> > no URL to call.
> >> >
> >> > /Christian
> >> >
> >> > On Tue, Feb 21, 2012 at 15:34, Martin Grigorov <[email protected]>
> >> wrote:
> >> >> Have you tried with org.apache.wicket.markup.html.include.Include ?
> >> >> It does exactly what you need.
> >> >>
> >> >> On Tue, Feb 21, 2012 at 3:20 PM, Johan Isaksson <[email protected]>
> >> wrote:
> >> >>> Hi!
> >> >>> Seven days ago I posted a question on the users mailing list (see
> >> below),
> >> >>> but I have got no responses so far. I thought I'll give it a try
> with
> >> the
> >> >>> developers list as well. Since my question to the users list I also
> >> found
> >> >>> that our 1.4 approach is very much alike what's described on the
> Wicket
> >> >>> wiki
> >> >>>
> >>
> https://cwiki.apache.org/WICKET/including-jsp-files-in-html-templates.html
> >> .
> >> >>> So there might be more projects bumping into this issue soon.
> >> >>>
> >> >>> I also posted this question on SO,
> >> >>>
> >>
> http://stackoverflow.com/questions/9257706/wicket-1-5-and-jsp-servlet-wrapping
> >> >>>
> >> >>> Thanks,
> >> >>>
> >> >>> Johan
> >> >>> ---------- Forwarded message ----------
> >> >>> From: Johan Isaksson <[email protected]>
> >> >>> Date: 2012/2/14
> >> >>> Subject: Wicket 1.5 and JSP/servlet wrapping
> >> >>> To: [email protected]
> >> >>>
> >> >>> Hi!
> >> >>>
> >> >>> In the project I'm on we want to upgrade from Wicket 1.4 to 1.5
> >> (1.5.4) and
> >> >>> 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()
> >> >>> *
> >> >>>
> >>
> (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
> container
> >> tag
> >> >>> "<wicket:container></wicket:container>".
> >> >>> * I also tried without invoking markupStream.next() as that step is
> >> >>> performed in Component.internalRenderComponent() just before
> >> >>> onComponentTagBody is invoked at all.
> >> >>> * move it to onComponentTag(ComponentTag tag)
> >> >>> * combined above with setting setRenderBodyOnly(true) in the
> >> >>> WebMarkupContatiner.onInitialize()
> >> >>> * use a <div> tag instead of a wicket: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.
> >> >>> * invoke getAssociatedMarkupStream() from onRender() but that raises
> >> the
> >> >>> following error
> >> >>> * org.apache.wicket.markup.MarkupNotFoundException: Markup of type
> >> 'html'
> >> >>> for component '... AbstractServletWrapperPanel$1' not found.
> >> >>>
> >> >>> 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
> >> >>>
> http://herebebeasties.com/2007-03-01/jsp-and-wicket-sitting-in-a-tree/
> >> >>>
> >> >>> I also posted this question on SO,
> >> >>>
> >>
> http://stackoverflow.com/questions/9257706/wicket-1-5-and-jsp-servlet-wrapping
> >> >>>
> >> >>> Any help solving this issue would be very appreciated!
> >> >>>
> >> >>> Thanks,
> >> >>>
> >> >>> Johan
> >> >>
> >> >>
> >> >>
> >> >> --
> >> >> Martin Grigorov
> >> >> jWeekend
> >> >> Training, Consulting, Development
> >> >> http://jWeekend.com
> >>
> >>
> >>
> >> --
> >> Martin Grigorov
> >> jWeekend
> >> Training, Consulting, Development
> >> http://jWeekend.com
> >>
>
>
>
> --
> Martin Grigorov
> jWeekend
> Training, Consulting, Development
> http://jWeekend.com
>