Java web architecture MVC (JSP/Servlets) - Modèle persistant

Bladrak

Membre actif
24 Mars 2004
600
78
37
Vincennes
Hello tous !

Je suis confronté à un soucis qui m'embête pas mal (normal pour un soucis me direz-vous).

Je suis en train de développer une grosse appli web en Java, en utilisant des JSP. J'ai relativement bien compris comment fonctionnait le système d'échanges Vue / Contrôleur (pages jsp / servlets), mais je bloque sur l'échange contrôleur / modèle.

J'ai vu qu'il existait des "Beans" pour le modèle, mais je n'ai pas l'impression que ça corresponde à mon besoin. En effet, j'ai des objets qui sont persistants, ou du moins communs pour tous mes utilisateurs, et je n'arrive pas à les récupérer. Je ne vois pas où les instancier de façon à ce qu'ils soient accessibles à tous mes servlets (dans l'idéal, au niveau de l'architecture, ils seraient situés "entre" les servlets et les modèles).

Typiquement, pour l'authentification d'un utilisateur sur le site, j'aimerais pouvoir récupérer un utilisateur qui a été instancié dans le modèle (qui est conservé dans l'UtilisateurManager).

Je ne sais pas si quelqu'un a une idée ? (Grumfffffffff si tu passes par là :p )

Si vous voulez un bout de code c'est pas un problème pour moi, mais ça risque d'être assez long :/ (vu qu'il faudrait que je mette le .jsp, la servlet et les modèles concernés)
 
Soit tu le fais crade en static, soit tu fais un singleton, google est ton ami. ;) Attention à gérer les accès concurrents. Et pour le mvc, fais pas ça à la mano, utilise struts, struts 2 ou jsf, ou encore Spring (qui peut te servir à plein d'autres choses), ça te facilitera grandement la vie.
Passe sur ichat si t'as besoin d'un coup de main. Là ça sent un peu l'architecture douteuse ton truc. :D
 
J'avais pensé à utiliser struts, mais vu que j'ai jusqu'à... vendredi pour finir le projet, ça va être tendu d'apprendre ça en 2 jours :D

Après avoir jeté un oeil sur les singletons, c'est pas mal en effet, je peux faire ça sur les Managers ?
Pis dernière pitite question : je les instancie quand du coup ? Dans le main controller ? Ça m'arrange pas des masses si je dois faire le load de toutes les données à chaque nouveau client...

Je ferai ptet un petit tour sur iChat demain dans la journée du coup ^^

Merci en tout cas ;-)
 
J'avais pensé à utiliser struts, mais vu que j'ai jusqu'à... vendredi pour finir le projet, ça va être tendu d'apprendre ça en 2 jours :D

Après avoir jeté un oeil sur les singletons, c'est pas mal en effet, je peux faire ça sur les Managers ?
Pis dernière pitite question : je les instancie quand du coup ? Dans le main controller ? Ça m'arrange pas des masses si je dois faire le load de toutes les données à chaque nouveau client...

Je ferai ptet un petit tour sur iChat demain dans la journée du coup ^^

Merci en tout cas ;-)

Struts ça s'apprend en 2Heures, pas en 2 jours, et ça te fera gagner plus de temps que t'en perdras à l'apprendre, tu prends le premier tuto que tu trouves sur developpez.com, tu le suis à la lettre et t'auras compris le principal. Dans la journée t'as aucune chance de me voir sur ichat, ou alors faut que je te file le msn du boulot, mais j'aime autant éviter :D. Tes managers devraient être des singletons (ou appartenir à un singleton plus exactement), instantiés au lancement de l'application, genre par une servlet, ou simplement au premier appel, c'est le principe d'un singleton.
 
Je suis pas certain d'avoir compris (C'est vrai qu'un bout de code serait bienvenu).

Pour pouvoir avoir des objets communs à tes servlets tu peux utiliser le ServletContext (ici).

(Si j'ai bien compris tu as une Servlet qui va lire dans ta base d'utilisateurs et qui donne des trucs à dire à ta page JSP ?)
 
@Grumff : C'est vrai que struts a pas l'air bien compliqué, mais il nécessiterait que je revoie tout le modèle (qui est déjà codé, et qui a près de 50 classes), ce qui ferait un peu long... Donc je vais probablement partir sur des managers en singleton. Mais y'a une petite chose que j'ai pas saisie : les variables instanciées dans les servlets le sont pas à chaque fois qu'un utilisateur y passe ? Si j'y passe une fois, la réinstanciation se fera pas au prochain utilisateur ?

@Lapin masqué : Le ServletContext répond malheureusement pas à mon problème (enfin jcrois pas).
Ptit bout de code alors :D

Le formulaire d'identification.jsp (pas finalisé) :
Bloc de code:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Identification</title>
</head>
<body>
<%
String mail = request.getParameter("mail");
String mdp = request.getParameter("mdp");
%>
<form action="ServletConnexion" method="post">
	<input type="text" value="<%=mail%>" name="mail"/>
	<input type="text" value="<%=mdp%>" name="mdp" />
	<input type="submit" value="connexion" />
</form>
	
</body>
</html>

La servlet (un peu fouillie, y'a du bordel dû aux tests) - j'y instancie les managers et un utilisateur de test :
Bloc de code:
package ctrl_touriste;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import race.Race;
import royaume.RoyaumeAlreadyExistsException;
import royaume.RoyaumeImpl;
import royaume.RoyaumeManager;
import serveur.Main;
import utilisateur.MotDePasseIncorrectException;
import utilisateur.Seigneur;
import utilisateur.SeigneurAlreadyExistsException;
import utilisateur.SeigneurManager;
import utilisateur.Utilisateur;
import utilisateur.UtilisateurAlreadyExistsException;
import utilisateur.UtilisateurInconnuException;

/**
 * Servlet implementation class ServletConnectionMail
 */
public class ServletConnexion extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private String defaultMail = null;
	private String defaultMdp = null;
	
	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ServletConnexion() {
		super();
		// TODO Auto-generated constructor stub
	}

	public void init() {
		ServletConfig config = getServletConfig();
		defaultMail = config.getInitParameter("mail");
		if (defaultMail == null)
			defaultMail = "Entrez votre adresse mail";
		defaultMdp = config.getInitParameter("mdp");
		if (defaultMdp == null)
			defaultMdp = "";
		new SeigneurManager();
		new RoyaumeManager();
		Race race = new Race("Elfe", null, null);
		RoyaumeImpl r1;
		try {
			r1 = new RoyaumeImpl(race, null, null, null, 0, 0, 0, null, null, null);
			try{
				Utilisateur seigneur = new Seigneur("Titre", "bg", 'M', null, r1, "nom", "mdp", null, "[email protected]");
			} catch (Exception e){
				System.out.println(e);
			} catch (UtilisateurAlreadyExistsException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SeigneurAlreadyExistsException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (RoyaumeAlreadyExistsException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// on r&#381;cupre les paramtres du formulaire
		String email = request.getParameter("mail");
		String mdp = request.getParameter("mdp");
		try {
			Seigneur s = SeigneurManager.identification(email, mdp);
		} catch (UtilisateurInconnuException e) {
			email = defaultMail;
			e.printStackTrace();
		} catch (MotDePasseIncorrectException e) {
			mdp = defaultMdp;
			e.printStackTrace();
		}
		// on affiche le formulaire
		request.setAttribute("mail", email);
		request.setAttribute("mdp", mdp);
		getServletContext().getRequestDispatcher("/JSP/identification.jsp").forward(request, response);
	}

}

Le côté modèle : classe Seigneur (extends Utilisateur) :
Bloc de code:
package utilisateur;
import royaume.*;
import TempsJeu.TempsJeu;

import java.util.GregorianCalendar;
import java.util.Date;

/**
 * 
 * @modelguid {C2F6AC04-6A89-4DD2-A721-C1EB04BB2C76}
 */
public class Seigneur extends Utilisateur {
	/**
	 * 
	 * @modelguid {0ECD180D-9179-4BE4-A7B3-37183EAFA67E}
	 */
		
	private String _titre;

	/**
	 * 
	 * @modelguid {B9B06086-4EDC-4415-9EDE-CFBA75F8C26E}
	 */
	private String _bakground;

	/**
	 * 
	 * @modelguid {5B65413F-96A7-43B6-815E-488DF4431E6D}
	 */
	private char _sexe;

	/**
	 * 
	 * @modelguid {317D2CED-373A-4038-A2EF-B340A98DE737}
	 */
	private TempsJeu _tempsJeu;

	/**
	 * 
	 * @modelguid {B214606E-B1B5-4B3E-AF87-395F3038CB09}
	 */
	private String _avatar;

	/**
	 * 
	 * @modelguid {CB2FDB71-5EA9-4EA0-BB63-D5AEB52D1182}
	 */
	private RoyaumeImpl _unRoyaume;
	
	
	public Seigneur(String a_titre, String a_background, char s, 
			String a_avatar,RoyaumeImpl a_royaume, String a_nom, String a_MDP, 
			String a_signature, String a_mail) throws UtilisateurAlreadyExistsException, SeigneurAlreadyExistsException{
		
		super(a_nom, a_MDP, a_signature, a_mail);
		
		SeigneurManager.AlreadyExists(a_nom, a_mail);
		
		this._titre = a_titre;
		this._bakground = a_background;
		this._sexe = s;
		this._unRoyaume = a_royaume;
		this._avatar = a_avatar;
		this._tempsJeu = new TempsJeu(0,0,0);
		SeigneurManager.AddSeigneur(this);
		
	}

	/** @modelguid {A09BD393-644F-4334-B5B7-E5976B087754} */
	public String get_titre() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _titre;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {93BBFF1D-9C9A-4427-88FD-2996E34564CE} */
	public void set_titre(String a_titre) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_titre = a_titre;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {A930A8CD-AFBE-4B1B-9BC7-055712E52818} */
	public String get_bakground() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _bakground;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {0ED60EF7-3B47-4833-B621-7B84E9B0C1FF} */
	public void set_bakground(String a_bakground) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_bakground = a_bakground;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {AB97F2EE-3C43-4842-AC4A-0E91114E6A88} */
	public char get_sexe() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _sexe;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {B4B0ACA4-6663-4213-BB15-831743C8111D} */
	public void set_sexe(char a_sexe) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_sexe = a_sexe;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {9313C5EE-05BB-4448-8964-5DA7F5DE9627} */
	public TempsJeu get_tempsJeu() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _tempsJeu;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {6F52C94C-6B75-4888-A295-0BDF0BC3DF76} */
	public void set_tempsJeu(int a_hours, int a_minutes, int a_second) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_tempsJeu.set_Hours(a_hours);
		_tempsJeu.set_Minutes(a_minutes);
		_tempsJeu.set_second(a_second);
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {0A19A312-C850-47A6-855E-A98E2ACA7A87} */
	public String get_avatar() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _avatar;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {2FA47CA4-CA8B-45E3-A517-5773EAD155DE} */
	public void set_avatar(String a_avatar) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_avatar = a_avatar;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

}

Classe utilisateur :
Bloc de code:
package utilisateur;
import java.util.GregorianCalendar;
/**
 * 
 * @modelguid {3C5C9679-96C2-4580-85AC-C5218FEC22CD}
 */
public class Utilisateur {
	/**
	 * 
	 * @modelguid {21EA4952-6EB1-4BB3-ABD7-D21BC275CF31}
	 */
	private String _pseudo;

	/**
	 * 
	 * @modelguid {47CC379E-C910-468D-B4D0-1DD7775D6CC4}
	 */
	private String _MDP;

	/**
	 * 
	 * @modelguid {B4BDA15A-E901-40B9-A283-C4105BFA4534}
	 */
	private String _signature;

	/**
	 * 
	 * @modelguid {49836478-43A4-462E-A9AC-C5CD14C12EAF}
	 */
	private String _mail;

	/**
	 * 
	 * @modelguid {748B947D-7D18-4127-84DC-0B61E9ABE65A}
	 */
	private GregorianCalendar _date;
	
	
	public Utilisateur(String a_pseudo, String a_MDP, String a_signature, String a_mail){
		
		this._pseudo = a_pseudo;
		this._MDP = a_MDP;
		this._signature = a_signature;
		this._mail = a_mail;
		this._date = new GregorianCalendar();

		}
	
	

	/** @modelguid {2C045939-E459-4E41-AB85-B118E5B5D048} */
	public String get_pseudo() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _pseudo;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {6083DFE0-1027-4663-813A-0A7B5EC57D98} */
	public void set_pseudo(String a_pseudo) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_pseudo = a_pseudo;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {BB057DFE-B3FD-43DE-BC07-5E6DB7F5CA99} */
	public String get_MDP() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _MDP;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {D8C7AA57-CD4E-4324-BEF1-11908AE3AC21} */
	public void set_MDP(String a_MDP) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_MDP = a_MDP;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {C9BE7D6E-A8B2-43C1-9DA3-31E091827AA2} */
	public String get_signature() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _signature;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {BC3E28D0-075F-4F1B-8162-6C225D69B1A4} */
	public void set_signature(String a_signature) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_signature = a_signature;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {555A799E-20CC-44AF-A955-C5C674E1CCF6} */
	public String get_mail() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _mail;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {CDEC07A4-450E-4381-9758-C07E39AE274E} */
	public void set_mail(String a_mail) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_mail = a_mail;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}

	/** @modelguid {8D51CB41-B2ED-4179-AA9D-FB701AA1DC16} */
	public GregorianCalendar get_date() {
		/*Begin Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
		
		return _date;
		/*End Template Expansion{D463887C-0F96-42C1-B8DC-90E8DC272BD5}*/
	}

	/** @modelguid {1890C6E3-E466-4EA1-94A8-708D06AB7C9B} */
	public void set_date(GregorianCalendar a_date) {
		/*Begin Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
		_date = a_date;
		/*End Template Expansion{CA3F77E8-8B8B-47C4-A1B8-CE1F21AEAEA5}*/
	}
	
	

	/**
	 * 
	 * @modelguid {D237A4C0-5A79-4602-ABF1-294EAE9BE57E}
	 */
	public void connection() {
	}

	/**
	 * 
	 * @modelguid {27D66A72-3C9F-4F6B-87F4-3E807BA5E44A}
	 */
	public void deconnection() {
	}

}

Puis le manager :
Bloc de code:
package utilisateur;

import java.util.ArrayList;
import java.util.Collection;

public class SeigneurManager {
	
	private static Collection<Seigneur> _lesSeigneurs;
	
	
	public SeigneurManager(){
		_lesSeigneurs = new ArrayList<Seigneur>();
	}
	

	public static void AddSeigneur(Seigneur a_seigneur){
		_lesSeigneurs.add(a_seigneur);
	}
	
	public static void AlreadyExists(String a_nom, String a_mail)throws SeigneurAlreadyExistsException, UtilisateurAlreadyExistsException{
		for(Seigneur _S : _lesSeigneurs){
			if(_S.get_mail().equals(a_mail)){
				throw new UtilisateurAlreadyExistsException();
			}
			if(_S.get_pseudo().equals(a_nom)){
				throw new SeigneurAlreadyExistsException(a_nom);
			}
		}
	}
		
	public static Seigneur identification(String mail, String mdp) throws UtilisateurInconnuException, MotDePasseIncorrectException {
		for (Seigneur s : _lesSeigneurs){
			if (s.get_mail().equals(mail)){
				if (s.get_MDP().equals(mdp))
					return s;
				throw new MotDePasseIncorrectException();
			}
		}
		throw new UtilisateurInconnuException();
	}
}
 
Bon je suis pas sûr d'avoir encore tout compris.

Si je crois ce que je lis : Tu entres ton nom d'utilisateur et ton mot de passe dans le formulaire, tu regardes si l'utilisateur existe et tu renvoies vers la page d'identification.

---

Ok si cela avait été moi, je récupérerais le Seigneur comme tu le fais, mais au lieu de renvoyer le nom d'utilisateur et le mot de passe, je mettrais directement l'objet Seigneur dans le HttpSession (request.getSession()) pour pouvoir m'en resservir plus tard.

Je ne capte pas trop le SeigneurManager, pourquoi a-t-il que des méthodes statiques ? (surtout avec ce constructeur) Le plus simple est d'en faire un objet normal, (de le singletonifier si tu veux) et de le mettre dans le ServletContext. Là il sera bien au chaud et c'est ton Tomcat qui va le dorloter. (Si tu tiens à le garder statique pour je ne sais qu'elle raison, met un bloc static {} pour instancier la liste au lieu de mettre ça dans le constructeur).

Ensuite le fait d'ajouter le Seigneur au manager directement dans son constructeur n'est pas propre. Ou bien tu veux qu'il soit ajouté dès son instanciation auquel cas tu passes le manager en argument dans le constructeur. Ou bien tu l'ajoutes extérieurement. C'est plus beau, plus propre et plus maintenable.

Pour les méthodes alreadyExists et identification, tu peux surcharger la méthode equals() de ta classe Seigneur et utiliser la méthode contains() de ta collection. C'est plus beau, plus propre et plus efficace que d'itérer toute la collection (auquel cas un basique array suffirait)

---

Sinon la fonction init() n'est appelée qu'une seule fois dans le cycle de vie de ta servlet, et tu peux très bien lui mettre des champs privés (pour tes managers notamment) pour t'en resservir plus tard. Ta conception actuelle est vachement trop complexe par rapport à ce que tu fais.

Bref tu peux partir avec des managers simples qui ne font qu'encapsuler des collections.
 
Bon je suis pas sûr d'avoir encore tout compris.

Si je crois ce que je lis : Tu entres ton nom d'utilisateur et ton mot de passe dans le formulaire, tu regardes si l'utilisateur existe et tu renvoies vers la page d'identification.

---
Pour l'instant ça fonctionne comme ça oui, mais il est prévu de stocker les infos de l'utilisateur en session :)

Je ne capte pas trop le SeigneurManager, pourquoi a-t-il que des méthodes statiques ? (surtout avec ce constructeur) Le plus simple est d'en faire un objet normal, (de le singletonifier si tu veux) et de le mettre dans le ServletContext. Là il sera bien au chaud et c'est ton Tomcat qui va le dorloter. (Si tu tiens à le garder statique pour je ne sais qu'elle raison, met un bloc static {} pour instancier la liste au lieu de mettre ça dans le constructeur).

Ensuite le fait d'ajouter le Seigneur au manager directement dans son constructeur n'est pas propre. Ou bien tu veux qu'il soit ajouté dès son instanciation auquel cas tu passes le manager en argument dans le constructeur. Ou bien tu l'ajoutes extérieurement. C'est plus beau, plus propre et plus maintenable.

Pour ça, c'est comme ça qu'on nous a appris. Du moins pour le manager. Je suppose qu'il y a une raison (ptet pédagogique ceci dit).
Edit : Le constructeur des managers va se complexifier après, on va y ajouter la récupération des données dans la base de données.

Pour les méthodes alreadyExists et identification, tu peux surcharger la méthode equals() de ta classe Seigneur et utiliser la méthode contains() de ta collection. C'est plus beau, plus propre et plus efficace que d'itérer toute la collection (auquel cas un basique array suffirait)
Ah ben je vais gueuler sur celui qui l'a codé :D Plus sérieusement, merci, j'avais pas pensé à ça. Par contre dans ce cas là je peux throw des exceptions dans le equals() surchargé ?

Sinon la fonction init() n'est appelée qu'une seule fois dans le cycle de vie de ta servlet, et tu peux très bien lui mettre des champs privés (pour tes managers notamment) pour t'en resservir plus tard. Ta conception actuelle est vachement trop complexe par rapport à ce que tu fais.

Bref tu peux partir avec des managers simples qui ne font qu'encapsuler des collections.

En fait je viens de réaliser que la servlet ne fonctionnait pas comme une session (et donc ne se "désinstanciait" pas à la fermeture de la page). Pas contre je comprends pas trop quand est-ce qu'elle est requise et détruite par le serveur ?

Merci pour vos réponses en tout cas, ça m'aide à mieux comprendre :)
 
Pour le manager s'il doit rester statique, alors c'est bon, par curiosité tu peux regarder du côté des patterns Factory et Singleton qui sont souvent utilisés pour gérer les Managers d'une application. (Le fait de faire la préparation de l'objet dans un bloc static {} t'évite d'utiliser un constructeur et d'instancier ta classe. (Mais montre assez rapidement ses limites si ça devient complexe =D)

Pour le Object.equals(), tu ne pourras pas lancer des exceptions à l'intérieur mais rien ne t'empêche de faire un <code>if xx.equals("yy") throw new MonException()</code> La méthode actuelle n'est pas foncièrement mauvaise mais c'est vrai qu'avec une grosse base ça peut vite devenir lourd. (Sinon tu peux aussi tout stocker dans un tableau et utiliser Arrays.binarySearch(), mais c'est plus tordu à utiliser et les gains en perfs ne seront pas si intéressants)

Le cycle de vie d'une servlet est :
Au démarrage du serveur Tomcat (je suppose),la servlet est lancée : elle est instanciée et la fonction init() est appelée.
A chaque fois qu'elle reçoit une requête la fonction service() est appelée. (Dans le cas d'une servlet HTTP tu as directement accès à doGet() doPost() doPut() etc..)
Au moment où Tomcat est arrêté, la servlet est stoppée, l'objet est disposé et le ramasse-miette va s'en charger toussa.

Quand tu utilises request.setAttribute() tu peux envoyer des infos à la page JSP mais ces infos ne restent pas après.

Si tu veux stocker des infos dans la session d'un utilisateur tu dois utiliser request.getSession()

Si tu veux stocker des infos dans la servlet c'est getServletContext()
 
T'es pas en php, toute ton appli se recharge pas à chaque fois que tu charges une page. ;) Donc oui les données ne sont pas resetées à chaque fois. ;) à part bien sur les objets instanciés dans le dopost et les fonctions qu'il appelle, donc attention à gérer les accès concurrents.
Rien à dire de plus que Lapin sinon, d'autant qu'il a eu plus le temps que moi de regarder ton code.

J'en remets une couche sur Struts, ça va se brancher avant ta couche métier, ça impactera quasiment pas tes jsp, t'auras un peu de copier/coller de code à faire de tes servlets vers tes actions struts, bref, je maintiens que le coût de mise en place est faible, et le gain important.
 
Merci pour vos aides en tout cas !

En effet j'ai un peu confondu avec PHP :D (Les habitudes ont la vie dure...)

Je pense que je me mettrai à Struts pour la prochaine appli. En tout cas quand je vois le JSP, je me dis que le PHP a d'énormes faiblesses quand même, malgré qu'il soit facile à apprendre pour un non-initié, les perfs laissent à désirer...
 
Merci pour vos aides en tout cas !

En effet j'ai un peu confondu avec PHP :D (Les habitudes ont la vie dure...)

Je pense que je me mettrai à Struts pour la prochaine appli. En tout cas quand je vois le JSP, je me dis que le PHP a d'énormes faiblesses quand même, malgré qu'il soit facile à apprendre pour un non-initié, les perfs laissent à désirer...


ca depend, php a des bonne perfs quand le code est bon quand je vois ton code servlet je me dis aussi que les perfs ne dois pas etre au rendez-vous c'est assez bordelique comme facon de coder, tu as un MVC sans reelement avoir un MVC, avoir un modele contenant 50 classes deja la j'y vois un gros probleme, strategic object, reflection et observer ecetera ce sont des concepts qui semblent t'echapper

mon simple sentiment: si j'etais ton manager je te dirais que c'est de la pisse d'ane ayant une sistite, tu pourrais eliminer 70% de ce que tu as ecris si tu programmais OO et c'est vraiment des conceptes en dehors du language

rm -Rf projet

et je sais tu ne vas pas m'aimer rien de personnel mais en tant que client je recois un tel code... le bizby commence

et php ne load pas tout a chaque fois... il cache le code et le garde, c'est objet persistent, c'est pour cela que ca memoire grossi comme la vm, et ca depend aussi des conf http/tcp keep-alive,TLS, pipelining, proxy ecetera mais cela est un autre debat... bien de choses qui sont toujours/tres souvant mal configures et mal comprises

:zen:
 
C'est vrai que le java c'est performant que quand c'est bien optimisé.

Et pour avoir un truc bien optimisé il faut que ton modèle soit super stable.

Une fois que tu as un modèle bien fait, il faut coder le reste, si tu veux bien améliorer ton codage en java, un petit passage par les Design Patterns risque de t'aider en te forunissant des solutions génériques et performantes (et souvent assez élégantes) à des problèmes connus.

Un autre truc que tu pourrais faire est d'user (et d'abuser) des interfaces pour toutes tes classes qui ne sont pas des Beans du modèle afin de pouvoir avoir une architecture bien solide mais de pouvoir avoir le fonctionnement interne plus modulaire.

Je serais mois sévère que tatouille cependant, le code est a améliorer mais c'est déjà pas mal.
 
Hello,

Je pense à peu près pareil que tatouille sur la qualité du code, mais je serais plus indulgent: on a tous commencé à zéro... il faut bien apprendre! ;)

Quelques remarques en vrac :
- design: le Seigneur ne doit pas connaître le SeigneurManager, mais c'est plutôt une autre classe qui doit créer un Seigneur et l'enregistrer auprès du SeigneurManager
- il ne faut jamais catcher les exceptions pour en faire un printStackTrace() : soit laisser l'exception remonter jusqu'en haut ; soit la capturer et la traitement proprement ; soit l'encapsuler dans une nouvelle et la rejeter plus haut si c'est possible d'ajouter une information intéressante
- ne jamais faire System.out.println() -> utiliser un framework de logging pour ça (exemple : Log4J)
- ne jamais capturer Exception
- ne pas utiliser new GregorianCalendar() mais faire Calendar.getInstance() qui va te retourner une nouvelle instance de GregorianCalendar ou d'un autre type de Calendar suivant ta localisation
- il te faut lire les code conventions de Sun pour le nommage des attributs et méthodes : http://java.sun.com/docs/codeconv/ (attribut ne doit pas commencer par "_" ; les méthodes doivent commencer par minuscule, y compris méthode static)
- tu as un problème potentiel de concurrence : SeigneurManager contient une ArrayList qui n'est pas synchronizée, plusieurs Thread vont y avoir accès et ça peut poser problème
- il n'y a pas de raisons à ce que SeigneurManager soit tout static ; les méthodes ne doivent pas être statique ; au pire, crée un singleton pour cette classe (SeigneurManager.getInstance())
- (programme en anglais!)
 
Je ne suis pas d'accord pour ton premier point molgow, c'est une manière de coder en contrôle inverse, mais ça demande une autre manière de penser et là c'est mal impléménté.

Pour synchroniser ta liste tu peux utiliser Collections.synchronizedList();

Mais je persiste à dire qu'avant de s'occuper de tels détails cosmétiques il faut revoir le modèle.
 
Je prends pas mal vos critiques, au contraire, ça me permet de m'améliorer ! :)

Pour ma défense je dirai juste que je débute, que je suis pas le seul à coder ce projet (on est 6), et qu'une bonne partie du code est générée par XDE (c'est moche :/ ).

C'est le premier projet web qu'on fait en java (le plus complexe qu'on ait fait auparavant c'était un chat en architecture client/serveur et ressources partagées).

Pour le manager bizarrement c'est mon prof qui nous a appris à faire comme ça (l'ajout dans le constructeur de la classe).

@ Tatouille : quand je disais 50 classes j'éxagérais ^^ (je dois plus être proche de 20-30, le nombre étant surtout lié à la complexité du projet - il s'agit d'un jeu par navigateur, donc beaucoup de process et concepts à gérer) Mais quand tu parles de strategic object, reflection et observer (à moins que ça soit le verbe :D ) je connais pas du tout...

Quoiqu'il en soit si je persiste là-dedans j'irai me renseigner plus du côté des frameworks et des "jolis" codes.
 
Je ne suis pas d'accord pour ton premier point molgow, c'est une manière de coder en contrôle inverse, mais ça demande une autre manière de penser et là c'est mal impléménté.

Pour moi le SeigneurManager est un controller, le Seigneur est un model. Et dans ce n'est donc pas au Seigneur de connaître le SeigneurManager.
Maintenant, le design est parfois subjectif, on peut toujours discuter.

Mais je persiste à dire qu'avant de s'occuper de tels détails cosmétiques il faut revoir le modèle.

Je suis pleinement d'accord avec ça :up:
 

Sujets similaires