RSS Feed

Articles associés au tag ‘jsp’

JSP 2.0, JSTL 1.1 – impossible d’utiliser les expressions languages dans des taglibs

16 August 2006 par SeB Pas de commentaire »

Vous vous êtes décidé d’écrire les pages JSP 2.0 avec la JSTL 1.1 le tout en XML[1]. Il faut dire au revoir aux scriptlets et bonjour aux EL ! ;-) Mais vous rencontrez peut-être cette erreur :

org.apache.jasper.JasperException: /index.jsp(33,32) According to TLD or attribute directive in tag file, attribute value does not accept any expressions
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	java.lang.reflect.Method.invoke(Method.java:585)
	org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:243)
	java.security.AccessController.doPrivileged(Native Method)
	javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
	org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:275)
	org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:161)
	java.security.AccessController.doPrivileged(Native Method)
	java.security.AccessController.doPrivileged(Native Method)
	org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1085)
	org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestProcessor.java:263)
	org.apache.struts.tiles.TilesRequestProcessor.processTilesDefinition(TilesRequestProcessor.java:239)
	org.apache.struts.tiles.TilesRequestProcessor.internalModuleRelativeForward(TilesRequestProcessor.java:341)
	org.apache.struts.action.RequestProcessor.processForward(RequestProcessor.java:572)
	org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:221)
	org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
	org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	java.lang.reflect.Method.invoke(Method.java:585)
	org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:243)
	java.security.AccessController.doPrivileged(Native Method)
	javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
	org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:275)
	org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:161)

Votre page JSP commence sûrement par quelque chose qui ressemble à ceci :

<jsp:root
	xmlns:jsp="http://java.sun.com/JSP/Page"
	xmlns:c="http://java.sun.com/jstl/core"
	xmlns="http://www.w3.org/1999/xhtml"
	version="2.0">

Si c’est le cas, la déclaration ci-dessus correspond à la JSTL 1.0.

Le problème vient du fait que vous utilisez un moteur JSP 2.0 qui traite les EL avant d’appeler les taglibs. Ce moteur n’est pas compatible avec les taglibs qui intègrent la gestion des EL comme le fait la JSTL 1.0. Pour résoudre ce problème, il faut utiliser la JSTL 1.1 qui est faite pour les JSP 2.0.

Pour déclarer l’utilisation des JSTL 1.1, votre page JSP doit commencer ainsi :

<jsp:root
	xmlns:jsp="http://java.sun.com/JSP/Page"
	xmlns:c="http://java.sun.com/jsp/jstl/core"
	xmlns="http://www.w3.org/1999/xhtml"
	version="2.0">

Je profite pour vous rappeler les excellentes présentation d’adiGuba sur :

Vous allez enfin pouvoir écrire des JSP 2.0 tout en utilisant la puissance des EL.

Notes

[1] Appelées également JSPX.

 

Les bonnes pratiques avec Struts – proteger l’accès des pages JSP

7 July 2006 par SeB Pas de commentaire »

Voici un premier billet dans la série sur Les bonnes pratiques avec Struts.

Introduction

La sécurité des applications web est un point sensible. En effet, il y a toujours un utilisateur qui essaie de casser la sécurité du système. Ce type d’utilisateur cherche dans le code source des pages HTML des informations sur le chemin des pages JSP. Ensuite, il tente de les exécuter manuellement et de modifier les données du contexte.

Solutions

Pour se prémunir de ce genre d’attaque, il faut interdire l’accès aux pages JSP par les utilisateurs. Deux méthodes sont possibles :

  • la configuration de l’application web
  • l’organisation des pages

Configuration de l’application web

Il faut simplement ajouter les lignes suivantes dans le fichier web.xml :

<security-constraint>
   <web-resource-collection>
     <web-resource-name>no_access</web-resource-name>
     <url-pattern>*.jsp</url-pattern>
   </web-resource-collection>
   <auth-constraint/>
 </security-constraint>

Organisation des pages

Le répertoire WEB-INF n’est pas accessible par les utilisateurs d’une application web. Il suffit donc de placer toutes les pages JSP dans ce répertoire[1]. Ensuite les redirections dans Struts doivent pointer vers /WEB-INF/... au lieu de /....

Conclusion

Je préfère la seconde solution[2] qui autorise plus de souplesse. Vous remarquez que les deux méthodes sont très simples et ne demande que très peu d’effort. Pourtant elles améliorent la sécurité[3] de vos applications web. Alors, n’hésitez pas à sécuriser l’accès de vos pages JSP.

Notes

[1] Par exemple, dans WEB-INF/pages ou WEB-INF/jsp.

[2] C’est également la solution que l’on rencontre le plus.

[3] Également la stabilité.

 

Des attributs dynamiques dans les TagLibs

27 April 2006 par SeB Pas de commentaire »

Comment procéder pour créer ses propres TagLibs acceptant des attributs dynamiques ?

C’est à cette question que cet article tente de répondre par un simple exemple. Les TagLibs permettent aux développeurs de pages JSP d’implémenter leurs propres tags JSP qui exécutent du code Java plus ou moins complexe. Pour rendre ce code paramétrable, il est possible d’utiliser les attributs du tag.

Exemple simple

Voici un exemple d’implémentation de taglib avec la classe com/company/project/HelloTag.java :

package com.company.project;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class HelloTag extends TagSupport {
	private String from = null;
	private String to = null;
	public void setFrom(String from) {
		this.from = from;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public int doStartTag() throws JspException {
		try {
			pageContext.getOut().println	("Hello <blink>"+to+"</blink>"+(from!=null?", I'm "+from:"")+".");
		} catch (IOException e) {
			throw new JspException ("I/O Error", e);
		}
		return SKIP_BODY;
	}
}

Sa défintion dans WEB-INF/ht.tld :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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>1.0</tlib-version>
	<jsp-version>1.2</jsp-version>
	<short-name>ht</short-name>
	<uri>ht</uri>
	<display-name>Hello tag</display-name>
	<description>Hello tag</description> 	<tag>
		<name>hello</name>
		<tag-class>com.company.project.HelloTag</tag-class>
		<body-content>empty</body-content>
		<attribute>
			<name>from</name>
			<required>false</required>
		</attribute>
		<attribute>
			<name>to</name>
			<required>true</required>
		</attribute>
	</tag>
</taglib>

Et la page JSP l’utilisant index.jsp :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0" xmlns:ht="/WEB-INF/ht.tld">
<html xmlns="http://www.w3.org/1999/xhtml"> <head>
	<title>Hello tag</title>
</head>
<body>
	<ht:hello to="you" from="me" /><br />
	<ht:hello to="you" />
</body>
</html>
</jsp:root>

Cet exemple fonctionne assez bien et affiche le texte suivant :

Hello you, I'm me. Hello you.

Cependant, les attributs to et from sont souvent amenés à être dynamiques. C’est à dire, qu’ils peuvent être le résultat d’un scriptlet ou d’expressions languages. Malheureusement le code ci-dessus ne fonctionne pas avec des attributs dynamiques.

Les scriptlets

Si la page JSP est modifiée pour utiliser un scriptlet ainsi :

	<ht:hello to="<%=request.getParameter("name")%>" from="me" />

Le résultat de l’exécution de la page en passant la valeur pipo au paramètre name est :

Hello <%=request.getParameter("name")%>, I'm me.

Pour que le scriptlet soit évalué, il est nécessaire de modifier la définition du taglib de manière à préciser que les attributs du tags peuvent être le résultat de scriptlets :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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>1.0</tlib-version>
	<jsp-version>1.2</jsp-version>
	<short-name>ht</short-name>
	<uri>ht</uri>
	<display-name>Hello tag</display-name>
	<description>Hello tag</description> 	<tag>
		<name>hello</name>
		<tag-class>com.company.project.HelloTag</tag-class>
		<body-content>empty</body-content>
		<attribute>
			<name>from</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>to</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
</taglib>

Avec cette modification, le taglib fonctionne mieux et donne le résultat suivant :

Hello pipo, I'm me. Hello you.

Les expressions languages

Les scripltets sont très bien. Mais depuis JSP 2.0 et aujourd’hui avec JSP 2.1, il est préférable d’utiliser les expressions languages. La page JSP utilisant ces expressions est la suivante :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0" xmlns:ht="/WEB-INF/ht.tld">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>Hello tag</title>
</head>
<body>
	<ht:hello to="${param.name}" from="me" />
</body>
</html>
</jsp:root>

A l’exécution de cette page, le résultat obtenu est le suivant :

Hello ${param.name}, I'm me.

L’expression language n’est pas interprétée. Pour résoudre ce problème, il est nécessaire de modifier le code du taglib. Voici la version améliorée et supportant les expressions languages :

package com.company.project;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
public class HelloTag extends TagSupport {
	private String from = null;
	private String to = null;
	public void setFrom(String from) {
		this.from = from;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public int doStartTag() throws JspException {
		try {
			String fromEL = (String)ExpressionEvaluatorManager.evaluate("from", this.from, String.class, this, super.pageContext );
			String toEL= (String)ExpressionEvaluatorManager.evaluate("to", this.to, String.class, this, super.pageContext );
			pageContext.getOut().println	("Hello <blink>"+toEL+"</blink>"+(fromEL!=null?", I'm "+fromEL:"")+".");
		} catch (IOException e) {
			throw new JspException ("I/O Error", e);
		}
		return SKIP_BODY;
	}
}

Cette fois, la page affiche correctement le message :

Hello pipo, I'm me. Hello you.

Maintenant ce taglib paramétrable accepte les attributs dynamiques. Ainsi le code HTML généré pourra dépendre du contexte de l’utilisateur.