2009-12-24 4 views
0

Je veux lier les paramètres d'un ServletRequest à des objets de domaine arbitraires. Params sont disponibles comme une carte de typeComment lier les paramètres ServletRequest aux objets de domaine?

Map<String, String[]> // String = key, String[] = values 

Ils doivent être convertis et liés aux champs de l'objet cible. Id aiment avoir une méthode comme ceci:

// definition: 
public void bind(Map<String, String[]>, T target) 

// usage: 
bind(request.getParameterMap(), domainObject); 

Quelle est la meilleure façon de lier les paramètres de requête à un objet de domaine dans un Java Servlet? Quelles sont les librairies disponibles à cet effet ou comment en écrivez-vous une?

+1

La liaison de données est un problème complexe, pour toutes les applications, sauf les plus triviales. Les frameworks Web consacrent beaucoup d'efforts à cela, et vous ne devriez pas vous attendre à trouver une solution facile en faisant rouler la vôtre. Les frameworks existent pour une bonne raison :) – skaffman

Répondre

0

Je dirais que cela dépend de quel type d'objet est le vrai domainObject. Si c'est un haricot, vous pouvez utiliser une réflexion à base automatisée haricot populator comme mon BeanPropertyController(c'est gratuit afin de lui donner un essai de licence est ASF2.0!) pour effectuer les opérations suivantes:

/* Assumed parameter input: 
* a=hello 
* c=123 
* e=f,g,h 
* 
* Matching bean: 
*/ 
public class ParamBean { 
    private String a; 
    private int c; 
    private String[] e; 
    /* + all the normal getters and setters you'd see in a bean */ 
} 

/* somewhere in your servlet: */ 

BeanPropertyController bpc = BeanPropertyController.of(ParamBean.class); 

for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) { 
    bpc.mutate(entry.getKey(), 
       getNiceValue(entry.getValue(), bpc.typeOf(entry.getKey())); 
} 

ParamBean bean = bpc.getObject(ParamBean.class); 

/* somewhere else in the class */ 

public Object getNiceValue(String[] objs, Class<?> desiredClass) { 
    if (objs.length == 1) { 
     Object o = objs[0]; 
     return convertString(o); 
    } else { 
     Object[] newObjs = Object[objs.length]; 

     for (int i=0;i<objs.length;i++) { 
      newObjs[i] = convertString(objs[i]); 
     } 

     return (Object) newObjs; 
    } 
} 

private Object convertString(String value, Class<> desiredClass) { 
    if (Number.class.isAssignableFrom(desiredClass)) { 
     Double d = null; 
     try { 
      d = Double.parseDouble(value) 
     } catch (NumberFormatException e) { 
      // Not of the desired type, do whatever you want 
     } 
     if (Double.class.isAssignableFrom(desiredClass)) { 
      return d; 
     } else if (Long.class.isAssignableFrom(desiredClass)) { 
      return d.longValue(); 
     } else if (Integer.class.isAssignableFrom(desiredClass)) { 
      return d.intValue(); 
     } // and so on... 
    } else if (Boolean.class.isAssignableFrom(desiredClass)) { 
     try { 
      return Boolean.valueOf(value); 
     } catch (NullPointerException e) { 
      // Not of the desired type, do whatever you want 
     } 
    } else { 
     return value; // or whatever your default type is 
    } 
} 
+0

Pour mon cas d'utilisation, la méthode getNiceValue serait la plus intéressante. J'ai besoin de quelque chose pour la conversion réelle d'une carte plane à une structure d'objet. – deamon

+0

Assez juste, exemple de code mis à jour. Il peut être buggé cependant, je suis actuellement loin de mon ordinateur à la maison et j'ai dû utiliser Notepad. Joyeux Noël! – Esko

1

Avez-vous regardé dans la Spring MVC (http://springsource.org) cadre du tout? Il fournit une fonctionnalité de liaison que vous pouvez utiliser en dehors du printemps. Aussi, si vous n'utilisez pas actuellement un autre framework MVC, c'est un bon outil à considérer.

Questions connexes