Aide - Recherche - Membres - Calendrier
Version complète : [jsp / java] scope balise à scriplet et regex
Forum Développeur - Administration serveur, programmation et base de données > Programmation > Java
wox-xion
Bonjour à tous ! smile.gif
Le post concerne deux points :

La manipulation du scope d'une variable dans une page jsp

et

L'utilisation des regex en java

[°Scope d'une variable]

Voilà, lorsque j'utilise des scriplets ET des balises jsp, comment récupérer une variable d'une balise dans un scriplet et inversément ?

CODE
<c:set var="maVar" value="${1+2}" />

<%

int maVar = 1+3;

%>

<c:out value="${maVar}" />

<%= maVar %>


bien sûr, là, je vois bien que j'ai deux scopes différentes, mais comment communiquer et recevoir la variable définie par <c:set /> dans mon scriplet ???


[°Utilisation des regex]

Je connais les regex pour php, donc via ereg, et surtout, preg_replace & co, cependant, pour java, je ne connais pas du tout...
Est-ce que quelqu'un pourrait m'aider ?

Quelles sont les classes, méthodes, fonctions, et utilisations, et si vous avez des exemples, ça pourrait m'aider...
J'aurai besoin de savoir principalement comment vérifier si un pattern regex est présent dans une chaîne de charactères, et de pouvoir modifier une chaîne via des méthodes équivalent le preg_replace de php :wink:
jep
Bon, alors moi, c'est claire, j'y connais rien en Java... mais au vu de ton problème, mon premier reflexe ce serait google :wink:
> http://www.google.fr/search?q=java+regexp

Puis aussi :
> http://java.developpez.com/

et donc :
> http://cyberzoide.developpez.com/java/regex/
wox-xion
oui, je viens de tomber avant sur http://cyberzoide.developpez.com/java/regex/


ça m'aide pour les regex, mais pas entièrement, car voici un code donné :

CODE
// compilation du regex avec "thé"

Pattern p = Pattern.compile("thé");



// création du moteur associé à la regex sur la chaîne "J'aime le thé."

Matcher m = p.matcher("J'aime le thé.");



// remplacement de toutes les occurences de thé" par "chocolat"

String s = m.replaceAll("chocolat");


seulement, ça ne remplace pas totalement preg_replace par exemple, car comment faire pour pouvoir chercher selon un pattern "\[IMG]]*)\]" et remplacer chaque occurence trouvée par "<img src='\\1' /> où \\1 vaut la valeur du premier GROUPE (([^\]]*)) trouvé par le pattern ?
wox-xion
bon, bas, j'ai l'impression d'avoir trouvé une réponse depuis cet email :

http://www.mail-archive.com/java@u-strasbg...r/msg04070.html

donc je pourrai utiliser replaceAll(pattern, "$1") où $1 est la valeur du premier groupe trouvé, or ceci est donc fait pour les Strings... j'espère que ça marche pour les regex, mais je ne vois pas pourquoi ça n'irait pas...

par contre, l'utilisation de $1 porte largement à confusion, car le charactère $ est utilisé pour les variables php, et je ne vois pas ce qu'il fait là, mais bon, si quelqu'un a plus d'infos, merci :wink:


MAIS ce n'est pas terminé, car j'aimerai bien qu'on me réponde pour l'autre question, la première même :roll:
liguorien
salut smile.gif [quote]Voilà, lorsque j'utilise des scriplets ET des balises jsp, comment récupérer une variable d'une balise dans un scriplet et inversément ? [/quote]tu veux mixer des scriplets et des tags custom !?! ohmy.gif L'utilisation des scriptlet est maintenant déconseillé en JSP 2.0. Il est préférable d'utiliser les tags custom et l'EL. smile.gif [quote]par contre, l'utilisation de $1 porte largement à confusion, car le charactère $ est utilisé pour les variables php, et je ne vois pas ce qu'il fait là, mais bon, si quelqu'un a plus d'infos, merci [/quote] euh... c'est pas du PHP, c'est du Java... normal :mrgreen: @++
wox-xion
bon, donc si je comprends bien, le mieux, c'est d'utiliser des servlets lorsque j'ai un grand processus à faire, est soit d'utiliser un servlet directement, ou des beans qui s'occuperaient de faire mes traitements, et de renvoyer ça à ma page jsp, tout avec des balises ? :roll:

maintenant, j'aimerai juste savoir, si j'ai un servlet, si j'ai un bean, je dois compiler ma classe avant de l'envoyer sur le server où il la compile directement, et dois-je la répertorier dans web.xml ou juste importer la classe depuis la jsp ? :?
wox-xion
mince, je me suis mal exprimé... pour les bean, je vois bien comment l'utiliser :
CODE
<jsp:useBean id="beanNom" class="path.to.class" scope="application" />


mais est-ce que je peux appeler une classe et en créer un objet sans utiliser un scriplet ?

juste une question encore : je peux utiliser l'EL dans tout paramètre de balise jsp ? même un scope, un nom de variable, etc. ou seulement un paramètre "value" ?
liguorien
Dis donc, tu es curieux :mrgreen:

Je ne crois pas que je pourrai répondre à tout tes question en un seul post. Mais je vais t'expliquer le principe de base des bean et JSP.

Habituellement, on sépare le traitement de la requête en deux.

:arrow: On prépare l'information à afficher.

:arrow: On affiche l'information


La méthode la plus utilisé est de faire la première étape dans un Servlet avec du vrai code et ensuite envoyer le data au JSP pour générer le HTML.


le bean

CODE
class OS{

  private String _name;

  public String getName(){

      return _name;

  }

  public void setName(String n){

      _name = n;

  }

}


exemple dans le Servlet :

CODE
ArrayList liste = new ArrayList();



//on rempli l'ArrayList de Bean à partir d'une connexion BD

OS os1 = new OS();

os1.setName("Linux");



//on ajoute le bean a la collection

liste.add(os1);





request.setAttribute("liste_OS", liste); //dans le scope request



request.getSession().setAttribute("liste_OS", liste); //dans le scope session



request.getSession().getServletContext().setAttribute("liste_OS", liste); //dans le scope application



dans le JSP :

CODE
<c:forEach var="os" items="${requestScope.liste_OS}">

 <p>

     <c:out value="${os.name}"/>

 </p>

</c:forEach>


Voila, en gros le principe est de séparer la logique de l'affichage.

@++
wox-xion
d'accord, donc là, je vois un peu, mais ce que je ne comprends pas, c'est comment le passage se fait ou plutôt "comment ça s'organise" ?

j'ai donc une classe java qui est le bean
j'ai une classe qui est une servlet (que j'indexe dans mon web.xml)
et la jsp, en fichier normal .jsp

maintenant, la requète sera dirigée sur la servlet, non ?
alors la jsp ne sera pas traîtée pour l'instant, si je comprends ?

c'est soit la servlet, soit la jsp, tandis que le bean peut être utilisé par une servlet ou par une jsp, non ? :roll:
wox-xion
parce que si une personne va sur ma servlet, la servlet va afficher une page html, donc la jsp n'est pas visible, elle n'a rien à voir, je dois donc rediriger la requète sur la jsp, après avoir terminé la servlet, mais comment fais-je ?
liguorien
ouep, j'avais oublié ce détail important :oops:

CODE
request.getRequestDispatcher("page.jsp").forward(request, response);


wink.gif
wox-xion
ah, je vois, donc :

-la servlet fait le traitement, sauvegarde ça dans des variables qui ont une scope assez grande pour que la jsp puisse afficher les données
-la jsp affiche les données qui ont été traitées dans la servlet, sans avoir à passer par GET ou POST...

ingénieux, j'y avais pas pensé... merci beaucoup wink.gif
brunosite
Bonjour tlm,

j'ai un assez gros problème et je tourne assez en rond, je début en jsp alors soyez pas trop indulgent.

pour le code

Code

<c:forEach var="os" items="${requestScope.liste_OS}">

<p>

    <c:out value="${os.name}"/>

</p>

</c:forEach>


C'est quoi exactement le code complet à mettre dans le jsp? J'ai essayé plein de truc avec ou sans <% .. %> et des boucles for simple, mais là je suis bien paumé icon_cry.gif

J'utilise tomcat 5.5.9 sous winXP

merci d'avance

wox-xion
salut brunosite...

d'abord, tu dois créer les déclaration des balises dans le début de ton fichier jsp :

Code
<%@taglib uri='http://java.sun.com/jstl/core' prefix='c' %>
<%@page isErrorPage="false" pageEncoding="UTF-8" %>


ensuite, tu dois faire inclure les informations à propos des tags dans ton fichier web.xml qui se trouve dans :
$CATALINA_HOME/webapps/TON_APPLICATION/WEB-INF/web.xml

Tu peux trouver des infos sur le site de tomcat : http://jakarta.apache.org/tomcat/

Si tu utilises netbean pour tes applications, ayant la dernière version, tu as même la possibilité (dans le cadre d'un projet web), d'accéder à web.xml d'une manière décrite... et beaucoup plus simple...

Pour ce qui est de jstl, tu peux les télécharger ici : http://jakarta.apache.org/taglibs/index.html

La librairie par défaut est celle-ci : http://jakarta.apache.org/taglibs/doc/stan...-doc/intro.html

Mais vérifie bien que tu aies les version adéquates wink.gif (je sais pas si jstl est déjà inclu dans tomcat)

pour ce qui est de ton code... bas il te manque donc les déclarations des balises au sommet du fichier, et surtout, je ne vois pas qu'est-ce que fait requestScope.liste_OS

requestScope, oki, mais liste_OS n'existe pas par défaut non ?
c'est une collection sûrement (étant donné qu'il est traité via forEach), mais elle vient d'où ? icon_rolleyes.gif

EDIT : arghk, je suis idiot, c'est dans le post de liguorien icon_mrgreen.gif (faut avouer que ça date bientôt d'une année, donc m'en rappelais plus)

bon, et bien :
-> pour le bean, tu dois le mettre dans ton répertoire de classes
/webapps/MON_APPLICATION/WEB-INF/classes

-> pour la servlet, de même que le bean, mais par contre, tu dois la décrire dans web.xml
web.xml, c'est là où tu décris ton application (les librairies de tags, les servlets, les variables d'environnement, le fichier de base, les filtres, les listeners, etc.)

-> pour la jsp, bas il t'a montré le corps de la page, mais tu dois mettre les définitions des balises, au sommet...

C'est assez compliqué, donc trouve un projet déjà fait (tu peux regarder le projet d'exemples de tomcat et le décortiquer, c'est une très bonne chose pour apprendre) wink.gif
brunosite
Salut,

un très grand merci pour ton aide, ca fonctionne.

Je me suis fait un p'tit objet Personne méthode getXXX setXXX (qui est donc un JavaBeans si j'ai tout compris) et ensuite dans mon jsp je fais une boucle du même style que liguorien:

Code

<html>
<body>
<%@taglib uri='http://java.sun.com/jstl/core' prefix='c' %>
<%@page isErrorPage="false" pageEncoding="UTF-8" %>

<c:forEach var="p" items="${requestScope.listePersonne}">

<p>
    <c:out value="${p.nom}"/>
</p>
</c:forEach>
</body>
</html>



J'aurais encore quelque questions:

- Est-on obligé de faire autant de manipulation pour mettre en place un schéma MVC.
Avec comme entrée un servlet (qui dédié eventuellement certains boulots a d'autres servlets) discutant avec les classes métiers java. et renvoyant le résultat du servlet sur les pages jsp ?

- J'ai essayé un peu les exemples de tomcat, mais j'ai pas trouvé grand qui m'intéresse. Bon les bases d'opérande dans jsp et tout le reste, je connais je fais du java. Le truc c'est juste de pouvoir mettre en place le mvc, et là:
servlet => classe métiers OK
servlet => jsp OK

Donc si je me trompes pas, je sais le faire?


- J'ai pas trop compris comment s'était possible de faire carrément passer des objets dans les requetes entre servlet et jsp via les objets: HttpServletRequest. (je pourais éventuellement l'admettre c pas bien grave smile.gif )

- C'est quoi exactement ces différents: le scope request, session, application?

- ensuite il me restera à faire une session pour faire une page de login, tu as des url, cours, suggestions, ou autre à me faire?

merci pour ta patience. gourou.gif
wox-xion
Salut, pour ce qui est de la structure, c'est édivemment plus long à mettre en place qu'un script php qui n'importe rien, mais tu verras vite... quand ta structure est faite, tu peux faire des choses cent fois plus simplement icon_mrgreen.gif
et là, ça devient très agréable wink.gif

pour ce qui est des scopes... bas il y a :
-pageScope : portée de la page
-requestScope : portée de la requête
-sessionScope : portée de la session (pour tes systèmes de session, bas t'en a un de base icon_biggrin.gif)
-applicationScope : portée de l'application (j'ai pas bien compris jusqu'où ça va, je crois partout dans ton application, mais bon...

mise à par ces objets, tu en as d'autres implicites :
param : conteneur des paramètres GET ou POST > s'accède via param.nomdelavariable
paramValues : la même chose, mais te renvoie une collection de Strings
header : bas, ça se comprend
headerValues : pas besoin d'expliquer
initParam : paramètres d'initialisation du Context
cookie : valeur d'un cookie (et hop, très simple à utiliser)
pageContext : l'objet pageContext de la jsp

pour ce qui est de passer des variables dans request, c'est la même chose pour chaque scope (page, request, session, application) :
<%
session.setAttribute("nom", "valeur (n'importe quel type)");
%>
puis
<%
String attribute = (type de la valeur) session.getAttribute("nom");
%>

Mais bon, liguorien l'a dit, les jsp, c'est fait pour la visualisation, donc traite les données par servlet... et évite les scriplets wink.gif
wox-xion
ah, note aussi que la complexité de la structure te permet de faire énormément de choses... récemment, pour mon blog, j'ai créé un tag personnalisé, pour affiché un gravatar à partir d'une adresse email icon_mrgreen.gif

tu peux décrire totalement ton application, créer des nouvelles balises, des filtres qui sont invokés directement (pour l'encodage par exemple), des écouteurs de tes applications, pour faire du log par exemple, ...


pour ce qui est des objets qui comportent
-type getValue()
-setValue(type value)
-type value

oui, ce sont des JavaBeans icon_smile.gif
liguorien
"" a dit :
- J'ai pas trop compris comment s'était possible de faire carrément passer des objets dans les requetes entre servlet et jsp via les objets: HttpServletRequest. (je pourais éventuellement l'admettre c pas bien grave smile.gif )

- C'est quoi exactement ces différents: le scope request, session, application?


Ce sont ces 2 points qui font une grande différence entre développer en PHP ou Java. Le principe fondamentale des application web Java c'est que c'est une application bien normal (on ne le démarre qu'une seule fois) et tout se fait sout forme de classes. Tomcat transforme les JSP en Servlet en arrière plan. Si tu es curieux, tu peux aller voir le code Java généré à partir du JSP à l'endroit suivant :

/INSTALLATION_DE_TOMCAT/work/localhost/tonsite/*

ATTENTION, le code généré n'est vraiment pas séduisant, coeur sensible s'abstenir icon_mrgreen.gif Mais bon, il est tout de même fonctionnel le code wink.gif




Pour en revenir à mon explication initial, tout est un objet. Donc lorsque Tomcat recoit une requête il instancit un nouvel objet représentant une requête et l'envoi au servlet. Le fait que l'application ne soit chargé qu'une fois et que tout est en objet, ça facilite grandement le stockage(et réutilisation) des données en mémoire.

Lorsque l'on envoie un objet d'un Servlet à un JSP, tout se fait dans la même requête, l'objet n'est pas envoyé à traver le web.

Je vais reprendre l'explication des scope de xion (qui était bien, mais pas complète wink.gif)

- page : Ce scope représente la page. Il contient les objet qui sont déclaré dans la page. Si tu inclus un JSP à l'intérieur d'un autre, les 2 n'auront pas le même scope 'page'.

- request : Ce scope représente la requête actuelle. Que ce soit dans le servlet ou dans n'importe quel niveau d'imbrication de JSP, ce sera toujours le même scope. (les objet stocké dedans n'y sont que pour le temps de la requête)

- session : La session de l'usager

- application : les plus intéressant de tous. Ce scope est unique à ton application (contexte). Ça permet de partager et réutiliser des ressources pour tous les requêtes. Par exemple, je dois faire un formulaire sur un portail qui contient la liste de tout les pays du monde. Je crée un ArrayList et le rempli à partir d'une BDD dans la méthode init() d'un servlet. Ensuite on peut utiliser la liste de tout les pays sans faire aucune requête à la BD.



Dernier point, il est facultatif de spécifier le scope dans le JSP. L'évaluateur d'expression fera une recherche dans l'ordre suivante :

- page
- request
- session
- application

L'ordre de recherche est également un outil très puissant, suposons que j'ai ce code dans un fragment JSP :
Code

<select name="pays">
 <c:forEach var="pays" items="${listePays}">
   <option value="${pays.code}">${pays.titre}</option>
 </c:forEach>
</select>


Au lancement de l'application je remplis ma liste de pays. Donc je pourrais inclure ce JSP n'importe ou et il m'afficherait la liste de tout les pays. Si par exemple un jour ton boss vient te voir et dis que la liste doit être différente dans certaine page. Et bien c'est facile, il suffit de créer lors de la requête la nouvelle liste requise et la mettre dans le scope request (avec le même nom). Donc pour cette requête, ce sera la liste de pays dans le scope request au lieu que ce soit celui de application.

halala, je sens que je me perd dans mon explication, j'espère que je suis comprenable icon_lol.gif



"xion" a dit :
<%
session.setAttribute("nom", "valeur (n'importe quel type)");
%>


pas de scriplet icon_twisted.gif icon_razz.gif

l'équivalent avec les tag c'est :

Code
<c:set var="nom" value="valeur" scope="session" />

(si on ne spécifie pas le scope, celui par défaut est 'page')
wox-xion
argh, sorry icon_mrgreen.gif
où ça un scriplet je_sors.png

question comme ça, quand j'utilise <c:forEach>, la variable qui est passée en paramètre, elle doit être d'un type implémentant Collection, c'est bien ça ?
brunosite
wox-xion > à mon avis, effectivement ca doit etre une collection, dans arraylist et vector doivent passer.


Merci beaucoup pour toutes vos explications, j'avance beaucoup grace à vous smile.gif

icon_arrow.gif 1

Actuellement j'ai une servlet qui recoit par méthode POST d'un jsp un utilisateur et un mot de passe.
Elle se connecte à la base mysql, fait une requete et se deconnecte.

Si l'identification echoue:

Code
req.setAttribute("message","l'identification a échouée");
req.getRequestDispatcher("/jsp/login.jsp").forward(req, res);


Pourtant dans le jsp si je fais:

Code
<%
String msg = request.getParameter("message");
if (msg != null) out.println("message: "+msg);
out.flush();
%>


message est null, mais si je fais comme vous m'avez dit, (oui ca rentre doucement wink.gif ) et ben ca marche !

Code
<%@page language="java" %>
<%@taglib uri='http://java.sun.com/jstl/core' prefix='c' %>
<%@page isErrorPage="false" pageEncoding="UTF-8" %>
[ ... ]
<c:out value="${requestScope.message}"/>


Mais j'ai pas compris pourquoi la première solution ne marche pas? pourtant si je mets à la main dans la barre d'adresse login.jsp?message=test ca passe.

icon_arrow.gif 2
Comme vous venez de le voir j'attaque les bases de données. On a parlé que l'on pourrait remplir des objets à l'init d'un servlet et n'accèder qu'à ces objets ensuite sans faire de multiple requêtes SQL. Le problème c'est la portée de ses variables, elles sont accessibles par un client unique? et de même on pourrait par exemple ordonner la supression des objets par un destroy on je ne sais quoi.
Ensuite je pourrais éventuellement utiliser un scope application si je ne me trompe pas.

icon_arrow.gif 3
Pour les bases de données j'ai entendu qu'il fallait plutot utiliser un pool de connection, ou alors mettre les blocs en synchronized, je dois plutot utiliser un pool ( exemple: http://christophej.developpez.com/tutoriel/j2ee/pooltomcat/ ) . Dans l'état actuel, j'ai easyPhp et tomcat qui tourne, de mon servlet j'appelle une classe java que j'avais assez bien faite, plouf je lui passe "host","database","user","mdp" et hop ca me fait la connection, puis je fais un "select count(*) from utilisateur where user = ...", mais c peut être mal de faire comme ca? non ?

icon_arrow.gif 4

pour les Tag Library j'ai trouvé cette documentation, ca me parait quand même bien loin de ce que j'ai vu dans mon cours, m'enfin si ca marche comme ca

http://java.sun.com/products/jsp/jstl/1.1/...docs/index.html

Bye
liguorien
icon_arrow.gif 1 Il y a une différence entre request.getParameter() et request.getAttribute(). Les paramêtres sont les infos envoyé dans l'url et ne peuvent être que des String. Par exemple si j'ai maPage.jsp?sectionId=14, je peux faire request.getParameter("sectionId").

Pour récupurer les infos stocker via un setAttribute() il faut utiliser getAttribute().

Sinon pour ce qui est de ce code :
Citation :
Code
<%
String msg = request.getParameter("message");
if (msg != null) out.println("message: "+msg);
out.flush();
%>


Tu peux faire plus simple avec :

Code
${message}


smile.gif

wox-xion
salut

Pour ce qui est d'initialiser tes données pour les bases de données, c'est ce qu'il faut faire, mais attention à ce que tu veux dire.
D'abord, le pool de connection qui va avec tomcat : http://jakarta.apache.org/commons/pool/

Ensuite, à l'initialisation :
ActionScript
public class MaServlet extends HttpServlet {

private BasicDataSource _datasource;

/** Initializes the servlet.
*/

public void init(ServletConfig config) throws ServletException {
super.init(config);

_datasource = new BasicDataSource();
_datasource.setDriverClassName(config.getInitParameter("database-driver-class"));
_datasource.setUsername(config.getInitParameter("database-login"));
_datasource.setPassword(config.getInitParameter("database-password"));
_datasource.setUrl(config.getInitParameter("database-url"));
_datasource.setPoolPreparedStatements(true);
}
...


Ensuite, tu crées tu crées ton objet Connection lors de l'appel à une méthode de traitement (doGet ou doPost), et tu l'instancies alors, puis tu fais tes requêtes à l'intérieur de ta fonction...
En tout cas, c'est ce que je fais... maintenant, vu que Liguorien est plus aware que moi en java, je lui laisse la parole... icon_mrgreen.gif

au passage, comme tu le vois dans le code en-dessus, l'objet passé en paramètre te permet d'accéder à la configuration de ta servlet dans web.xml... simple d'utilisation et de modification wink.gif
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'informations, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2008 Invision Power Services, Inc.