8

contrôleur A Rails rend très facile à prendre en charge plusieurs types de contenu.prenant en charge plusieurs types de contenu dans un contrôleur Spring MVC

respond_to do |format| 
    format.js { render :json => @obj } 
    format.xml 
    format.html 
end 

Belle. Dans une action de contrôleur, je peux facilement répondre à plusieurs types de contenu avec beaucoup de flexibilité quant à ce que je souhaite rendre, que ce soit un modèle, une forme sérialisée de mon objet, etc.

Puis-je faire quelque chose de similaire à ceci dans Spring-MVC? Quelle est la norme pour la prise en charge de plusieurs types de contenu au printemps? J'ai vu des solutions impliquant des résolveurs de vue, mais cela semble difficile à gérer, surtout si je veux supporter JSON en plus de xhtml et xml.

Toutes les suggestions sont appréciés, mais les solutions plus simples et plus élégantes seront appréciés plus;)

EDIT

Si je me trompe en affirmant qu'un résolveur de vue est difficile à gérer, s'il vous plaît N'hésitez pas à me corriger et à donner un exemple. De préférence, celui qui peut renvoyer xml, xhtml et JSON.

Répondre

7

Au printemps 3, vous voulez utiliser le org.springframework.web.servlet.view.ContentNegotiatingViewResolver.

Il faut une liste de type de média et ViewResolvers. De l'Spring docs:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
    <property name="mediaTypes"> 
    <map> 
     <entry key="atom" value="application/atom+xml"/> 
     <entry key="html" value="text/html"/> 
     <entry key="json" value="application/json"/> 
    </map> 
    </property> 
    <property name="viewResolvers"> 
    <list> 
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/jsp/"/> 
     <property name="suffix" value=".jsp"/> 
     </bean> 
    </list> 
    </property> 
    <property name="defaultViews"> 
    <list> 
     <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> 
    </list> 
    </property> 
</bean> 
<bean id="content" class="com.springsource.samples.rest.SampleContentAtomView"/> 

Le contrôleur:

import org.springframework.stereotype.Controller; 
import org.springframework.ui.ModelMap; 
import org.springframework.web.bind.annotation.RequestMapping; 

@Controller 
public class BlogsController { 

    @RequestMapping("/blogs") 
    public String index(ModelMap model) { 
     model.addAttribute("blog", new Blog("foobar")); 
     return "blogs/index"; 
    }  
} 

Vous aurez également besoin d'inclure les pots Jackson JSON.

+1

Est-ce aussi facile et «beau» que Rails? Non. Mais selon les normes Java, probablement aussi bon que nous allons l'obtenir. – Todd

+0

P.S. - J'ai seulement testé les types de contenu HTML et JSON. Je travaille sur l'atome, maintenant. – Todd

+0

@Todd: Merci! C'est un peu déroutant cependant. Si je renvoie la chaîne "blogs/index", comment mes vues interagissent-elles avec mon modèle? Je me attendais à retourner un objet ModelAndView, auquel nous passerions la chaîne « blogs/index », puis si le client a demandé JSON, Spring voudrais simplement ignorer cette chaîne et sérialiser l'objet par Jackson. Pouvez-vous expliquer comment votre exemple fonctionne? – Samo

0

va ici le contrôleur exemple de travail, qui rend JSON et HTML à la fois basée sur demande en-tête « Content-Type ».

import org.springframework.http.HttpStatus; 
import org.springframework.http.ResponseEntity; 
import org.springframework.util.MimeTypeUtils; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestHeader; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class PersonService { 
    @RequestMapping(value = "/persons/{userId}", method = RequestMethod.GET) 
    public ResponseEntity<?> getPersonByName(@RequestHeader("Content-Type") String contentMediaType, 
      @PathVariable("userId") String userId,@RequestParam("anyParam") boolean isAscending) throws IOException { 

     Person person = getPersonById(userId); 
     if (isJSON(contentMediaType)) { 
      return new ResponseEntity<Person>(person, HttpStatus.OK); 
     } 

     return new ResponseEntity("Your HTML Goes Here", HttpStatus.OK); 
     //Note: Above you could use any HTML builder framework, like HandleBar/Moustache/JSP/Plain HTML Template etc. 
    } 


    private static final boolean isJSON(String contentMediaType) { 
     if ("application/json".equalsIgnoreCase(contentMediaType)) { 
      return true; 
     } 

     return false; 
    } 

}