Archive September 2009

Toggle view

PhaseListener rendering a binary document (PDF)

Inspired by Cagatay Civici’s idea of having a phase listener rendering images I decided to replace my PDF rendering servlets from a product that I’m currently working on.

At the end of the RESTORE_VIEW phase the listener would decode the request URL and extract a managed property reference expression, create an EL expression and get the byte array for the binary document.

	public void afterPhase(PhaseEvent event) {
		String viewId = event.getFacesContext().getViewRoot().getViewId();
		if (viewId.startsWith(PDF_STREAM_VIEW_ID_PREFIX)) {
			String streamExpression = StringUtils.substringAfter(viewId, PDF_STREAM_VIEW_ID_PREFIX);
			ELContext elContext = event.getFacesContext().getELContext();

			byte[] bytes = (byte[]) event.getFacesContext().getApplication().getExpressionFactory()
					.createValueExpression(elContext, "#{" + streamExpression + "}", byte[].class).getValue(elContext);
			if (bytes != null) {
				HttpServletResponse response = (HttpServletResponse) event.getFacesContext().getExternalContext()
						.getResponse();
				response.setContentType("application/pdf");
				response.setContentLength(bytes.length);

				try {
					response.getOutputStream().write(bytes);
				} catch (Exception exception) {
					LOG.error(exception.getMessage());
				}
			}
			event.getFacesContext().responseComplete();
		}
	}

To display the binary document a matching URL needs to be generated. Here the <object> tag is used for displaying a PDF document. The URL part after “/pdf/stream/” is used as a part of a value expression for referencing the actual PDF binary document (here it is managedBeanName.propertyName).


	<object
		data="#{facesContext.externalContext.requestContextPath}/#{facesContext.externalContext.requestServletPath}/pdf/stream/managedBeanName.propertyName"
			type="application/pdf" />

JSF Challenge

I have started to work on a new internal project that eventually sometime might turn into a product. It’s relies in JavaServer Faces for the web UI layer. For deepening my knowledge of the JSF technology (after I haven’t worked with JSF for almost a year) I have decided to start my JSF Challenge that would accompany my project development.
My JSF Challenge means that whatever the problem is that has to be solved I would tackle it directly using no workarounds but would rather try to utilize the most efficient features of JSF.
Also that would mean that for many of these solutions I would strive to create solutions that are re-usable for other projects in future as well. So this would for example also involve creating custom JSF components and using more of the JSF APIs than I did in the past.

green red blue grey