• cdi
  • components
  • contexts
  • converters
  • eventlisteners
  • exceptionhandlers
  • facesviews
  • filters
  • functions
  • managedbeans
  • push
  • resourcehandlers
  • scripts
  • servlets
  • taghandlers
  • utils
  • validators
  • viewhandlers
-
  • ContextParam
  • Cookie
  • Eager
  • FacesConverter
  • FacesValidator
  • GraphicImageBean
  • Param
  • ViewScoped

Stereo type that designates a bean with one or more methods returning byte[] or InputStream as a named application scoped bean specifically for serving graphic images via <o:graphicImage> component or #{of:graphicImageURL()} EL functions.

import org.omnifaces.cdi.GraphicImageBean;

@GraphicImageBean
public class Images {

    @Inject
    private ImageService service;

    public byte[] get(Long id) {
        return service.getContent(id);
    }

}

When using @Named @ApplicationScoped instead, serving graphic images via a JSF page will continue to work, but when the server restarts, then hotlinking/bookmarking will stop working until the JSF page referencing the same bean method is requested for the first time. This is caused by a security restriction which should prevent users from invoking arbitrary bean methods by manipulating the URL. The @GraphicImageBean basically enables endusers to invoke any public method returning a byte[] or InputStream on the bean by just a HTTP GET request.

Usage

You can use #{of:graphicImageURL()} EL functions to generate URLs referring the @GraphicImageBean bean, optionally with the image type and lastModified arguments. Below are some usage examples:

<ui:repeat value="#{bean.products}" var="product">

    <!-- Basic, using default type and last modified. -->
    <a href="#{of:graphicImageURL('images.full(product.imageId)')}">
        <o:graphicImage value="#{images.thumb(product.imageId)}" />
    </a>

    <!-- With specified type and default last modified. -->
    <a href="#{of:graphicImageURLWithType('images.full(product.imageId)', 'png')}">
        <o:graphicImage value="#{images.thumb(product.imageId)}" type="png" />
    </a>

    <!-- With specified type and last modified. -->
    <a href="#{of:graphicImageURLWithTypeAndLastModified('images.full(product.imageId)', 'png', product.lastModified)}">
        <o:graphicImage value="#{images.thumb(product.imageId)}" type="png" lastModified="#{product.lastModified}" />
    </a>
</ui:repeat>

Note that in the #{of:graphicImageURL()} EL functions the expression string represents the same value as you would use in <o:graphicImage> and that it must be a quoted string. Any nested quotes can be escaped with backslash.

The type argument/attribute is the image type represented as file extension. E.g. "jpg", "png", "gif", "ico", "svg", "bmp", "tiff", etc. When unspecified then the content type will default to "image" without any subtype. This should work for most images in most browsers. This may however fail on newer images or in older browsers. In that case, you can explicitly specify the image type via the type argument/attribute which must represent a valid file extension.

The lastModified argument/attribute is the "last modified" timestamp, can be Long or Date, or otherwise an attempt will be made to parse it as Long. When unspecified, then the "default resource maximum age" as set in either the Mojarra specific context parameter com.sun.faces.defaultResourceMaxAge or MyFaces specific context parameter org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES will be used, else a default of 1 week will be assumed.

Demo

See <o:graphicImage> showcase page for the demo.