Je veux ajouter un paramètre à une HttpServletRequest...

Je veux ajouter un paramètre à une HttpServletRequest... - Java - Programmation

Marsh Posté le 29-04-2004 à 16:06:22    

Hello,
 
Bon, je sais que ça ne se fait pas, mais je veux le faire quand même ;)
 
Il n'y a pas de méthode setParameter(...), mais il y a une méthode getParameterMap(). Dans le cas de mon tomcat 4.1, getParameterMap() retourne une Map qui est en fait une http://jakarta.apache.org/tomcat/t [...] erMap.html
C'est une HashMap qui à la particularité de pourvoir être bloquée pour éviter un put(...) intempestif dessus.
 
Mais il y a une méthode setLocked(boolean locked)...
 
J'essaye donc ça :
 

Code :
  1. ...
  2. import org.apache.catalina.util.ParameterMap;
  3. public class PortalServlet extends HttpServlet
  4. {
  5.     protected void service( HttpServletRequest request, HttpServletResponse response )
  6.     {
  7.  if( request.getParameter( "page_id" ) == null )
  8.  {
  9.   ParameterMap y = (ParameterMap)request.getParameterMap();
  10.   y.setLocked( false );
  11.   y.put( "page_id", "1" );
  12.   y.setLocked( true );
  13.  }
  14.  ...
  15. }
  16. ...


 
Ca compile bien, mais à l'execution je me mange une "java.lang.ClassCastException" :cry:
 
Et je ma demande bien pourquoi :??:  
Qaund je regarde la classe de request.getParameterMap(), c'est pourtant bien une ParameterMap  :sweat:


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 29-04-2004 à 16:06:22   

Reply

Marsh Posté le 29-04-2004 à 17:02:06    

Bon, en cherchant un peu j'ai la solution "HttpServletRequestWrapper" :  
 

Code :
  1. public class PortalServlet extends HttpServlet
  2. {
  3.     private static final PortalJspBean portalBean = new PortalJspBean(  );
  4. String _nPageId = "0";
  5.     protected void service( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
  6.     {
  7.         super.service( request, response );
  8.  response.setContentType( "text/html" );
  9.  HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper( (HttpServletRequest) request )
  10.  {
  11.   public java.lang.String getParameter( java.lang.String name )
  12.   {
  13.    if( name.equals( "page_id" ) )
  14.    {
  15.     return _nPageId;
  16.    }
  17.    else
  18.    {
  19.     return super.getParameter( name ); 
  20.    }
  21.   }
  22.  };
  23.  // Code qui détermine la valeur de _nPageId...
  24.  ...
  25.  response.getOutputStream(  ).print( portalBean.getContent( wrapper ) );
  26. }
  27. }


 
Tout ça juste parce-que cette pu..... de M...... de Map n'est pas modifiable et que j'aime pas les redirects !


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 29-04-2004 à 23:01:31    

quel interet quand tu peux passer des objets dans la requete avec des setAttribute()?

Reply

Marsh Posté le 30-04-2004 à 08:46:24    

Mara's dad a écrit :

Bon, en cherchant un peu j'ai la solution "HttpServletRequestWrapper" :  


ouais c'est la solution ... Mais là fait gaffe, ton wrapper ne wrappe pas toutes les méthodes qui permettent de récupérer les paramêtres ... si tu attend cet aprem, je peux te filer une classe qui fait ca bien ...

Reply

Marsh Posté le 30-04-2004 à 14:57:11    

_guigui_ a écrit :

quel interet quand tu peux passer des objets dans la requete avec des setAttribute()?


L'intéret est de ne pas modifier les méthodes qui utilisent getParameter pour lire la valeur de page_id !
 

benou a écrit :

ouais c'est la solution ... Mais là fait gaffe, ton wrapper ne wrappe pas toutes les méthodes qui permettent de récupérer les paramêtres ... si tu attend cet aprem, je peux te filer une classe qui fait ca bien ...


Hein ?
T'as une liste des limitations, ou une doc ?
Parce-que la javadoc n'en parle pas, ou alors je ne sais pas la lire ;)


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 30-04-2004 à 17:13:14    

Mara's dad a écrit :

Hein ?
T'as une liste des limitations, ou une doc ?
Parce-que la javadoc n'en parle pas, ou alors je ne sais pas la lire ;)


pas besoin de doc, c'est juste que là tu as juste surchargé le getParameter(String). => si tu appelles getParameterMap(), getParameterValues(String)  ou getParameterNames(), comme tu n'as pas redéfinis ces méthodes, c'est les versions de l'objet parent qui seront utilisées => ton paramêtre supplémentaire à toi n'apparaitera pas => ta classe *bug*
 
kadô :

Code :
  1. public static HttpServletRequest getEnhancedParametersRequest(HttpServletRequest request, Map params) {
  2.  return new AddedParametersRequestWrapper(request, params);
  3. }
  4. public static HttpServletRequest getEnhancedParametersRequest(HttpServletRequest request, Map params, String method) {
  5.  return new AddedParametersRequestWrapper(request, params, method);
  6. }
  7. //...
  8. private static class AddedParametersRequestWrapper extends HttpServletRequestWrapper {
  9.  private Map params;
  10.  private boolean merged;
  11.  private String method;
  12.  public AddedParametersRequestWrapper(HttpServletRequest request, Map params) {
  13.   super(request);
  14.   this.params = params;
  15.   for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
  16.    Map.Entry entry = (Map.Entry) iter.next();
  17.    Object value = entry.getValue();
  18.    if (value instanceof String) {
  19.     entry.setValue(new String[] {(String) value});
  20.    }
  21.   }
  22.   merged = false;
  23.   method = request.getMethod();
  24.  }
  25.  public AddedParametersRequestWrapper(HttpServletRequest request, Map params, String method) {
  26.   super(request);
  27.   this.params = params;
  28.   for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
  29.    Map.Entry entry = (Map.Entry) iter.next();
  30.    Object value = entry.getValue();
  31.    if (value instanceof String) {
  32.     entry.setValue(new String[] {(String) value});
  33.    }
  34.   }
  35.   merged = false;
  36.   this.method = method;
  37.  }
  38.  public String getParameter(String name) {
  39.   String values[] = (String[]) this.params.get(name);
  40.   if ((values == null) || (values.length == 0)) {
  41.    if (merged) {
  42.     return null;
  43.    } else {
  44.     return super.getParameter(name);
  45.    }
  46.   } else {
  47.    return values[0];
  48.   }
  49.  }
  50.  public Map getParameterMap() {
  51.   if (! merged) {
  52.    Map paramMap = new HashMap(super.getParameterMap());
  53.    paramMap.putAll(this.params);
  54.    this.params = paramMap;
  55.    this.merged = true;
  56.   }
  57.   return this.params;
  58.  }
  59.  public Enumeration getParameterNames() {
  60.   return Collections.enumeration(this.getParameterMap().keySet());
  61.  }
  62.  public String[] getParameterValues(String name) {
  63.   Collection coll = this.getParameterMap().values();
  64.   return (String[]) coll.toArray(new String[coll.size()]);
  65.  }
  66.  public String getMethod () {
  67.   return this.method;
  68.  }
  69. }


en bonus tu peux même faire passer une méthode get pour une méthode post.
remarque : les subtilités genre ordre des paramêtres et émulation de l'inputstream ou de la querystring (dans le acs du changement de méthode) ne sont pas gérés.


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 30-04-2004 à 21:09:21    

Merci :jap:
 
M'enfin, pour l'appli en cours, je pense que ce que j'ai est suffisant.
 
Tout ça me laisse quand même perplexe :
Java en général et les 'libs' standards essayent par tous les moyens de rendre la programmation la plus safe possible en bloquant/limitant un max de choses.
 
Or, il est toujours possible de passer outre les limitations et interdictions. C'est généralement au prix de gros devs de contournement qui ajoutent donc complexité et donc source de bugs au système.
 
Un autre truc qui me gave, c'est par exemple les méthodes qui retournent des objets du type le plus basic possible genre Collection alors qu'en fait elles pourrait tout à fait retourner des ArrayList (le minimum instanciable) beaucoup plus pratiques à utiliser.
 
L'impression général est un peu le 'politiquement correct' poussé au maximum qui colle des oeillères tellement énormes que la réputation de lenteur de Java vient à mon avis moins des performances des JVM, mais plus des GigaMètres de codes encapsulés dans des myriades de coquilles vides !
 
Vive PHP !
 
Exemple, pour faire la même chose que le Wrapper que j'ai été obligé de coller dans mon appli :
 

Code :
  1. <?php
  2. ... code de détermination de $page_id...
  3. $_GET['page_id'] = $page_id;
  4. ?>


No more comment :ange:


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 30-04-2004 à 21:57:25    

le problème vient surement aussi que tu cherches à faire en java ce que tu fais en PHP.
 
Franchement, ajouter un paramêtre à une requête, c'est pas un truc qu'on fait tous les jours, et dans la logique c'est pas un truc qu'on devrait faire. en tout cas, pas dans une servlet (dans un filtre a la rigueur) ... D'ailleur, t'as pas expliqué pour quel besoin tu faisais ca. A tous les coups y avait moyen de s'en passer.
 
Sinon, pour le "politiquement correcte" et les "abstrations inutiles" des API Java, c'est de là que vient sa robustesse et son évolutivité. C'est une très bonne chose !
 
Ton histoire de Collection à la place d'ArrayList justement. Si ca te renvoie une Collection, c'est, logiquement, que tu n'as pas besoin de plus. Sinon ils t'auraient retourné une List. Mais de toute façon, jamais une ArrayList ! Ce serait idiot de se contrendre à l'utilisation d'un objet bien particulier.  
 
Mais bon, à tous les coups tu es de ceux qui aiment pas les itérateurs parce qu'ils sont trop habituées à leur boucles for indexée ;)
 
Alors que les itérateurs, c'est bon. Faut en manger ca donne des forces.
 
Bref, [:tonton_benou]
 
 
 
PS : vraiment, c'est pas beau de laisser ton code tel quel, hein :/ Elle est bancale ta HttpServletRequest, là  :(

Reply

Marsh Posté le 30-04-2004 à 23:57:05    

Désolé de te contredire mais une ArrayList EST une LIST et EST aussi une collection ! Qui peut le plus peut le moins et pas le contraire !
 
Robustesse mes couilles ! Je vois pas comment 20 000 lignes de code de contournement pour un cas particulier sont un gage de robustesse. Et si j'ai encore du boulot, jusqu'à preuve du contraire, c'est qu'il y à encore un paquets de cas particulier à traiter ;)
 
Les itérateurs, j'en mange tous les jours, et j'aime çà !
C'est juste un exemple de la réductionite aigüe que je constate.
 
Pourquoi j'ai besoin de modifier les paramètres d'une requête :
L'url d'une page de Lutece est de la forme suivante :
http://www.paris.fr/NOM_D_UNIVERS/ [...] _id=n2&...
 
Même la page d'acceuil du site est de cette forme ! Bref dans l'état de la V2 de lutece, www.paris.fr retourne une erreur 404 !
 
Donc, la servlet qui sert de point d'entrée doit faire le traitement suivant :
Si pas d'univers précisé : Univers=Portail avec page_id=Accueil
Si univers précisé mais pas page_id, prendre la page d'accueil de l'univers demandé (exemple : http://www.paris.fr/culture)
On trouve le N°de page dans une table. Il n'est donc pas question de passer par un filtre.
 
Une autre solution est de faire une redirection HTTP, mais bon je trouve que c'est quand même une solution bien naze !
 
D'autre part si le HttpServletRequestWrapper existe, c'est bien pour contourner non ? Pourquoi ne pas laisser le développeur faire sont boulôt !
 
Bref modifier un paramètre de la requête sert à traiter les cas par défaut histoire de ne pas accueillir que des programmeurs JAVA :D qui eux bien sûr savent que marcher hors des sacro-saint Design-Patterns c'est MAL... :ange:
 
M'enfin je t'en veux pas, je préfère la philosophie de Rasmus à celle de Sun c'est tout :)


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 01-05-2004 à 00:35:10    

pkoi tu fais pas bettement un dispatch avec des paramêtres suplémentaires ?
 
Sinon, pour ton qui peut le plus peu le moins, je suis absolument de l'avis inverse : qui n'a pas besoin de faire le plus, peu se contenter du moins. Ca laisse plus de marge d'évolution pour la suite ...

Reply

Marsh Posté le 01-05-2004 à 00:35:10   

Reply

Marsh Posté le 02-05-2004 à 01:05:10    

benou a écrit :

pkoi tu fais pas bettement un dispatch avec des paramêtres suplémentaires ?


 
J'ai pas compris là :??:
Le client envoie : http://www.paris.fr
L'appli doit comprendre : http://www.paris.fr/Portail/Portal [...] _id=12&...
 
Je fait comment concretemment, sachant que les IDs de page et autres sont récupérés par des requêtes SQL ?
 

benou a écrit :

Sinon, pour ton qui peut le plus peu le moins, je suis absolument de l'avis inverse : qui n'a pas besoin de faire le plus, peu se contenter du moins. Ca laisse plus de marge d'évolution pour la suite ...


 
Mais merde, c'est des Dieux qui écrivent les librairies, ou quoi ?
Qui peut se permettre de décrèter que le programmeur n'a pas besoin de plus ?
De toute façon, généralement, un cast suffit pour retrouver l'objet d'origine. Sauf avec org.apache.catalina.util.ParameterMap, et je ne comprends toujours pas pourquoi :??:
Le seul avantage que je vois, c'est dans certains cas d'éviter un import. Bien maigre je trouve.
Quand à l'évolution ! Parlons-en ! Lutece utilise Java 1.3 parce-que certaines parties de la V1 ne passent pas en 1.4 ! Pourquoi, mystère ?
Mais c'est à cause de ça que j'ai été obligé de faire ça : http://forum.hardware.fr/forum2.ph [...] 50#t694761
 
A+


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 02-05-2004 à 01:07:48    

Mara's dad a écrit :

J'ai pas compris là :??:
Le client envoie : http://www.paris.fr
L'appli doit comprendre : http://www.paris.fr/Portail/Portal [...] _id=12&...


this.getContext().getRequestDispatcher("/Portail/Portal.lut?page_id=12&..." ).forward("request, response);
[:spamafote]
 

Reply

Marsh Posté le 02-05-2004 à 01:12:11    

Mara's dad a écrit :

Mais merde, c'est des Dieux qui écrivent les librairies, ou quoi ?
Qui peut se permettre de décrèter que le programmeur n'a pas besoin de plus ?


mais bordel, ce qu'ils développent 'est pas un produit fini, c'est des spécifications. Donc peut importe l'implémentation qu'il y a derrière ne doit pas avoir d'importance. Si ils retourne une ArrayList, ca veur dire que tout doit être disponible. Si ils te renvoient juste un Iterateur par exemple, ca veut dire que l'implémentation derrière peut loader les truc au fur et à mesure  ... out tout d'un coup, comme elle veut.
 
Et si le développeur il veut une ArrayList à la place de sa collection, ben il se la fait et puis basta.

Reply

Marsh Posté le 02-05-2004 à 01:18:43    

:jap:
 
Ben voilà merci beaucoup, c'est exactement ce qu'il me faut !
 

Citation :

Franchement, ajouter un paramêtre à une requête, c'est pas un truc qu'on fait tous les jours, et dans la logique c'est pas un truc qu'on devrait faire.


 
On se demande bien à quoi peut servir un Dispatcher :D


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 02-05-2004 à 01:23:53    

benou a écrit :


Et si le développeur il veut une ArrayList à la place de sa collection, ben il se la fait et puis basta.


 
Ok, pas de problème.
Faut donc pas se plaindre si les applis Java font des kilomètres et trainent une réputation de lenteur.
 
Très bien je vais rentrer dans le rang. Quand on viendra me voir pour rendre le site plus rapide, je saurais quoi proposer :D


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 02-05-2004 à 03:02:33    

Mara's dad a écrit :

On se demande bien à quoi peut servir un Dispatcher :D


à passer la main d'une servlet à une autre ... le fait de passer des paramêtres supplémentaire est une facilitée ...

Reply

Marsh Posté le 02-05-2004 à 03:03:32    

Mara's dad a écrit :

Ok, pas de problème.
Faut donc pas se plaindre si les applis Java font des kilomètres et trainent une réputation de lenteur.


new ArrayList(taCollection) ca fait des kilomètres ca ? [:kiki]
 
 
ces développeurs php  :pfff:

Reply

Marsh Posté le 02-05-2004 à 05:54:02    

Mara's dad a écrit :

Mais merde, c'est des Dieux qui écrivent les librairies, ou quoi ?
Qui peut se permettre de décrèter que le programmeur n'a pas besoin de plus ?

Non, mais justement parce qu'ils sont incapables de fournir plus à l'utilisateur.
 
D'autre part "typer haut" (c'est une expression de moi) permet d'avoir un couplage faible.
 
 
edit : comme je suis parano face aux bidouilleurs comme Mara's dad, j'ai tendance à ne plus fournir que des objets de classe interne annonyme à l'utilisateur. Faire un cast là-dessus s'avère nettement plus compliqué (aller trouver le nom de la classe générée, rentrer dans le package etc.). La prochaine étape : je fais des objets-virus qui téléchargent du pr0n en image de fond et font sonner ton téléphone précisément au moment où tu t'assois dans ton bain.  
Sinon, il y a la solution de la classe Proxy (qui est complètement incastable).


Message édité par nraynaud le 02-05-2004 à 06:00:56

---------------
trainoo.com, c'est fini
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed