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" />

3 Comments

  • Lincoln Baxter - 2009/10/23

    I’d be interested to see a working example of this. Very cool!

    Reply
    • Fred Blogs - 2010/10/28

      I get #{…} not allowed in a template text body.

      Reply
      • Martin Ahrer - 2010/11/04

        It is very unlikely that anybody can help you with only so little information. I assume that you have some problem in your .xhtml file.

        Reply

Leave a Reply

green red blue grey