Accéder au contexte Spring depuis une JSP TagLibs JSTL

Lors d’un développement d’un projet web Spring, si vous utilisez les JSP, il est parfois utile de créer vos propres librairie de tag (ou taglibs). Malheureusement, au sein de ces taglibs,  il ne vous est pas possible d’accéder simplement au contexte d’application Spring pour y récupérer vos beans. Spring MVC met à disposition différentes solutions pour accéder aux contextes d’application que ce soit pour vos beans, vos traduction de Messages (MessageSource), votre Locale ou encore votre Theme.

Normalement, vos tags héritent de SimpleTagSupport ou n’importe quel autres classes héritant de TagSupport. Ces taglibs étant instancié par un constructeur new, ils ne peuvent ne peuvent pas bénéficier de l’injection automatique de dépendance de Spring ou d’accéder d’une manière plus général au contexte Spring. Il est toutefois possible de s’en sortir en utilisant la classe WebApplicationContextUtils. Il faut noter que cette solution n’est pas réservé qu’aux tags, et qu’elle peut être utilisé ailleurs dans votre projet

	/**
	 * Overwrite method.
	 * 
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 * @throws JspException
	 *             JspException
	 * @throws IOException
	 *             IOException
	 */
	public void doTag() throws JspException, IOException {
		ServletContext servletContext = ((PageContext) getJspContext()).getServletContext();
		ApplicationContext appContext =WebApplicationContextUtils.getWebApplicationContext(servletContext);
		//A utiliser pour récupérer un bean
		appContext.getBean("monBean");
		//Nécessite la Locale pour fonctionner
		appContext.getMessage(...); 
	}

Il est plus simple d’utiliser la classe RequestContextAwareTag et de faire hériter vos tags de celle-ci. La classe est disponible dans le paquet org.springframework.web.servlet.tags fournit avec le module Spring MVC, elle hérite de TagSupport.

La méthode doStartTag n’est pas à utiliser ici, elle se charge de remonter le contexte Spring et d’ensuite appeler doStartTagInternal

package demo.web.taglibs;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.tags.RequestContextAwareTag;

/**
 * @author Thibaut
 *
 */
public class DemoTagSpring extends RequestContextAwareTag {

	/**
	 * Cette méthode est appelée par la méthode doStartTag qui charge le contexte Spring
	 * préalablement . Overwrite method.
	 *
	 * @see org.springframework.web.servlet.tags.RequestContextAwareTag#doStartTagInternal()
	 * @return
	 * @throws Exception
	 */
	@Override
	protected int doStartTagInternal() throws Exception {
		//Récupération simple de l'applicationContext
		WebApplicationContext webApplicationContext = this.getRequestContext().getWebApplicationContext();
		//A utiliser pour récupérer un bean
		webApplicationContext.getBean("monBean");
		//A utiliser pour avoir la locale
		this.getRequestContext().getLocale();
		//a utiliser pour avoir une traduction, la locale est implicite dans ce cas car il s'agit du contexte de la page
		this.getRequestContext().getMessage("maKey");
		return 0;
	}
}

Attention, pour éviter une erreur du type NoSuchMethodError:setJspContext, il faut peut-être mettre à jour vos fichiers descripteur de tags, et surtout le numéro de version à utiliser pour les JSP.La méthode setJspContext n’est plus utilisée dans les versions récentes des librairies JSTL.

<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
    <tlib-version>2.5</tlib-version>
	<jsp-version>1.2</jsp-version>
    <short-name>mesTags</short-name>
    <uri>mesTags</uri>
    <tag>
        <name>DemoTagSpring</name>
        <tag-class>demo.web.taglibs.DemoTagSpring</tag-class>
        <body-content>scriptless</body-content>                        
    </tag>
</taglib>