2010-12-09 21 views
2

Ainsi, nous arrivons au point dans notre application Spring où nous devons décider comment gérer les vues et la négociation de contenu. Auparavant, nous ne prenions en charge qu'un type de contenu spécifique dans nos terminaux. Je vais lancer ce que je pense nos trois approches.Gestion de plusieurs types de contenu dans Spring MVC ... quelle approche est préférée?

Ma question: Lequel est généralement considéré comme la meilleure pratique/le moins de maintenance? Nous visons une convention solide à suivre dans notre application, qui peut être cassée si nécessaire pour fournir de la flexibilité si vous le souhaitez.

Première approche:
Utilisez ContentNegotiatingViewResolver. Cela impliquerait un mappage défini dans le fichier de servlet ... dans le contrôleur, chaque action du contrôleur aurait besoin de définir explicitement l'objet dans une carte en utilisant une chaîne magique. L'action du contrôleur retournerait une chaîne qui fait référence à un nom de modèle ... un peu comme les suivants:

@RequestMapping(value = "/someMapping/source", method = RequestMethod.GET) 
public String foo(Model model) 
{ 
    // more stuff here 
    model.addAttribute(SOME_MODEL_KEY, new ArrayList<String>() { "hello world"}); 

    return "someDummyJsonString"; 
} 

Désavantages:
Voir résolveurs semblent un peu trop compliqué ... ils ont des priorités, vous avez besoin pour les ignorer souvent, etc. De plus, je n'aime pas l'idée des "chaînes magiques" qui sont utilisées pour faire référence aux noms de bean template/View.

Deuxième approche:
Je pense que ce qui est nouveau au printemps 3.0, mais RequestMapping vous pouvez correspondre sur les en-têtes ... vous pouvez donc correspondre à l'en-tête Accepter comme ceci:

@RequestMapping(value="/someMapping", method = RequestMethod.GET, headers="Accept=application/json") 
public @ResponseBody SomeBar foo() 
{ 
    // call common controller code here 
    return buildBar(); 
} 

@RequestMapping(value="/someMapping", method = RequestMethod.GET, headers="Accept=text/xml") 
public String foo(Model model) 
{ 
    model.addAttribute("someModelName", this.buildBar()); 
    return "someTemplateNameProcessedByViewResolver"; 
} 

SomeBar buildBar() 
{ 
    return new SomeBar(); 
} 

Inconvénients:
Peut-être pas assez flexible? Je ne suis pas sûr, mais je pense que j'aime vraiment l'approche headers ... J'ai vu d'autres frameworks (RESTLet, Rails) utiliser quelque chose de similaire.

Troisième approche:
La troisième approche consiste à faire une coutume View qui négociera le contenu en fonction de l'en-tête Accept et jeter le modèle par la méthode appropriée. Ce point de vue de la négociation de contenu devrait connaître un modèle, et charger le modèle etc .:

@RequestMapping(value="/someMapping", method = RequestMethod.GET, headers="Accept=text/xml") 
public View foo() 
{ 
    SomeBar bar = new SomeBar(); 
    ContentNegotiatingView view = new ContentNegotiatingView(bar, "templateName"); 

    return return view; 
} 

:
Désavantages Il semble que le point de vue est en train de faire trop dans ce cas ... la vue serait regarder les en-têtes et définir le corps de la réponse lui-même. Il peut également être nécessaire de définir des statuts http. Donc, désolé pour le mur de texte, laissez-moi savoir ce que vous en pensez. Merci

Répondre

2

Quelqu'un d'autre juste asked this. Voir my answer.

+0

Ainsi, vous préféreriez l'approche résolveur de vue par rapport à l'approche d'annotation en-tête? – Polaris878

+0

À votre point de vue, l'approche du résolveur de vue semble plus flexible ... et semble être l'approche recommandée par le printemps, basée sur ma lecture des documents de toute façon. – Todd

+0

Hm, peut-être qu'après quelques années plus tard, nous aurions probablement tous plutôt envisager la solution d'annotation sur la solution de fichier de configuration XML :) –