This version allows you to use tag <wicket:jsp file="/foo.jsp"/> resolved automatically, or use as a customer wicket component <span wicket:id="jspId" /> with the ability to add some attributes to the request before JSP file is processed.
Custom JSP IcomponentResolver
public class WicketJspResolver implements IComponentResolver { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(WicketJspResolver.class); static { // Register the jsp tag within the wicket tag namespace WicketTagIdentifier.registerWellKnownTagName("jsp"); } public boolean resolve(final MarkupContainer container, final MarkupStream markupStream, final ComponentTag tag) { if (tag instanceof WicketTag) { WicketTag wtag = (WicketTag)tag; if ("jsp".equalsIgnoreCase(wtag.getName())) { String file = wtag.getAttributes().getString("file"); if (file == null || file.trim().length() == 0) { throw new MarkupException("Wrong format of <wicket:jsp file='foo.jsp'>: attribute 'file' is missing"); } // Add the jsp component to the component hierarchy container.autoAdd(new JspFileContainer(file), markupStream); // We did process the tag return true; } } // We did not process the tag return false; }
Custom HttpServletResponseWrapper
/** * Provides a convenient implementation of the HttpServletResponse interface. * This class implements the Wrapper or Decorator pattern. * Methods changing response headers does not affect original response. */ public class CharResponseWrapper implements HttpServletResponse { private CharArrayWriter output; public CharResponseWrapper() { super(); this.output = new CharArrayWriter(); } public PrintWriter getWriter() { return new PrintWriter(this.output); } @Override public String toString() { return this.output.toString(); } /* * From here, the methods have no effects */ public void addCookie(Cookie cookie) { // TODO Auto-generated method stub } public void addDateHeader(String name, long date) { // TODO Auto-generated method stub } public void addHeader(String name, String value) { // TODO Auto-generated method stub } public void addIntHeader(String name, int value) { // TODO Auto-generated method stub } public boolean containsHeader(String name) { // TODO Auto-generated method stub return false; } public String encodeRedirectURL(String url) { // TODO Auto-generated method stub return null; } @SuppressWarnings("deprecation") @Deprecated public String encodeRedirectUrl(String url) { // TODO Auto-generated method stub return null; } public String encodeURL(String url) { // TODO Auto-generated method stub return null; } @SuppressWarnings("deprecation") @Deprecated public String encodeUrl(String url) { // TODO Auto-generated method stub return null; } public void sendError(int sc) throws IOException { // TODO Auto-generated method stub } public void sendError(int sc, String msg) throws IOException { // TODO Auto-generated method stub } public void sendRedirect(String location) throws IOException { // TODO Auto-generated method stub } public void setDateHeader(String name, long date) { // TODO Auto-generated method stub } public void setHeader(String name, String value) { // TODO Auto-generated method stub } public void setIntHeader(String name, int value) { // TODO Auto-generated method stub } public void setStatus(int sc) { // TODO Auto-generated method stub } @SuppressWarnings("deprecation") @Deprecated public void setStatus(int sc, String sm) { // TODO Auto-generated method stub } public void flushBuffer() throws IOException { // TODO Auto-generated method stub } public int getBufferSize() { // TODO Auto-generated method stub return 0; } public String getCharacterEncoding() { // TODO Auto-generated method stub return null; } public String getContentType() { // TODO Auto-generated method stub return null; } public Locale getLocale() { // TODO Auto-generated method stub return null; } public ServletOutputStream getOutputStream() throws IOException { // TODO Auto-generated method stub return null; } public boolean isCommitted() { // TODO Auto-generated method stub return false; } public void reset() { // TODO Auto-generated method stub } public void resetBuffer() { // TODO Auto-generated method stub } public void setBufferSize(int size) { // TODO Auto-generated method stub } public void setCharacterEncoding(String charset) { // TODO Auto-generated method stub } public void setContentLength(int len) { // TODO Auto-generated method stub } public void setContentType(String type) { // TODO Auto-generated method stub } public void setLocale(Locale loc) { // TODO Auto-generated method stub }
Custom JSP File Container
public class JspContainer extends WebMarkupContainer { private final static Logger log = Logger.getLogger(JspContainer.class); private static final long serialVersionUID = 1L; /** path to JSP file */ private String _file; /** request attributes to be set before */ Map<String, Object> _requestAttributes; protected JspContainer(String file) { super(file); this._file = file; this._requestAttributes = null; setRenderBodyOnly(true); setAuto(true); } /** * Constructor. All components have names. A component's id cannot be null. This is the minimal * constructor of component. It does not register a model. * * @param id * The non-null id of this component * @param jspPath * context relative path the JSP file * @param requestAttributes * Map containing data put into the request Attributes before calling the JSP file */ public JspContainer(String id, String jspPath, Map<String, Object> requestAttributes) { super(id); this._file = jspPath; this._requestAttributes = requestAttributes; } /** * {@inheritDoc} * @see org.apache.wicket.MarkupContainer#onRender(org.apache.wicket.markup.MarkupStream) */ @Override protected void onRender(MarkupStream markupStream) { super.onRender(markupStream); } /** * {@inheritDoc} * @see org.apache.wicket.MarkupContainer#onComponentTagBody(org.apache.wicket.markup.MarkupStream, org.apache.wicket.markup.ComponentTag) */ @Override protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) { super.onComponentTagBody(markupStream, openTag); getResponse().write(getJSPOutput()); } /** * Retrieve the jsp output as a string * @return * the content of the result of the JSP request in a String */ protected String getJSPOutput() { ServletContext context = ((WebApplication) Application.get()).getServletContext(); try { // Make an attempt at locating the resource. // If it does not exist, the requestDispatcher.include will // simply ignore it. if (context.getResource(this._file) == null) { if (shouldThrowExceptionForMissingFile()) { throw new WicketRuntimeException(String.format("Cannot locate resource %s within current context: %s", this._file, context.getContextPath())); } else { log.warn( String.format("File will not be processed. Cannot locate resource %s within current context: %s", this._file, context.getContextPath()) ); } } } catch (MalformedURLException e) { throw new WicketRuntimeException(e); } WebRequestCycle cycle = (WebRequestCycle) RequestCycle.get(); ServletRequest request = cycle.getWebRequest().getHttpServletRequest(); ServletResponse jspResponse = new CharResponseWrapper(); // Set attributes to request, and store current attributes Map<String, Object> originalAttributes =null; if( this._requestAttributes != null ) { originalAttributes = new HashMap<String, Object>(); for (Entry<String, Object> attribute : this._requestAttributes.entrySet()) { String keyAttribute = attribute.getKey(); originalAttributes.put( keyAttribute, request.getAttribute( keyAttribute ) ); request.setAttribute( keyAttribute, attribute.getValue() ); } } try { context.getRequestDispatcher(this._file).include(request, jspResponse); } catch (ServletException e) { log.error("ServletException : ", e); throw new WicketRuntimeException(e); } catch (IOException e) { log.error("IOException : ", e); throw new WicketRuntimeException(e); } finally { /** * restore original attributes; */ if( originalAttributes != null) { for (Entry<String, Object> attribute : originalAttributes.entrySet()) { request.setAttribute( attribute.getKey(), attribute.getValue() ); } } } if (log.isDebugEnabled()){ log.debug(" JSP output ==" + jspResponse.toString()); } return jspResponse.toString(); } /** * Should we throw an Exception on JSP file missing ? * @return */ private boolean shouldThrowExceptionForMissingFile() { return Application.get().getResourceSettings().getThrowExceptionOnMissingResource(); } }
You can register the custom component in your application class for automatic use
protected void init() { getPageSettings().addComponentResolver(new WicketJspResolver()); }
Include the JSP file in your HTML template
<wicket:jsp file="/foo.jsp"/>
OR
You can add a component to your page
Map<String, Object> attributes =new HashMap<String, Object>(); attributes.put( "data", "insert some data available to JSP file"); add( new JSPContainer("jspId", "/WEB-INF/jsp/foo.jsp", attributes) );
Include the JSP file in your HTML template
<span wicket:id="jspId" />