Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

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.

Code Block
titleCustom 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;
	}
Code Block
titleCustom 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
	}
Code Block
titleCustom 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();
	}
}
Code Block
titleYou can register the custom component in your application class for automatic use
protected void init() {
    getPageSettings().addComponentResolver(new WicketJspResolver());
}
Code Block
titleInclude the JSP file in your HTML template
<wicket:jsp file="/foo.jsp"/>

OR

Code Block
titleYou 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) );
Code Block
titleInclude the JSP file in your HTML template
<span wicket:id="jspId" />