8

Un controlador Rails hace que sea muy fácil admitir varios tipos de contenido.Compatible con múltiples tipos de contenido en un controlador Spring-MVC

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

Precioso. En una acción de controlador, puedo responder fácilmente a múltiples tipos de contenido con mucha flexibilidad en cuanto a lo que deseo representar, ya sea una plantilla, una forma serializada de mi objeto, etc.

¿Puedo hacer algo similar a esto en Spring-MVC? ¿Cuál es el estándar para soportar múltiples tipos de contenido en Spring? He visto soluciones que implican la resolución de vistas, pero parece difícil de gestionar, especialmente si deseo admitir JSON además de xhtml y xml.

Se aprecia cualquier sugerencia, pero las soluciones más simples y más elegantes se apreciarán más;)

EDITAR

Si estoy equivoca al afirmar que una visión del resolver es difícil de manejar, por favor siéntete libre de corregirme y dame un ejemplo. Preferiblemente uno que puede devolver xml, xhtml y JSON.

Respuesta

7

En el resorte 3, desea utilizar el org.springframework.web.servlet.view.ContentNegotiatingViewResolver.

Toma una lista de tipo de medio y ViewResolvers. Desde el 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"/> 

El controlador:

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"; 
    }  
} 

También tendrá que incluir los frascos Jackson JSON.

+1

¿Es tan fácil y "hermoso" como Rails? No. Pero según los estándares de Java, probablemente sea tan bueno como lo que obtendremos. – Todd

+0

P.S. - Solo he probado los tipos de contenido HTML y JSON. Estoy trabajando en átomo, ahora. – Todd

+0

@Todd: ¡Gracias! Aunque es un poco confuso. Si devuelvo la cadena "blogs/index", ¿cómo interactúo alguno de mis puntos de vista con mi modelo? Esperaba que devolviera un objeto ModelAndView, al que le pasaríamos la cadena "blogs/index", y luego, si el cliente solicitaba JSON, Spring simplemente ignoraría esta cadena y serializaría el objeto a través de Jackson. ¿Puedes explicar cómo está funcionando tu ejemplo? – Samo

0

Aquí va el controlador de ejemplo de trabajo, que representa JSON y HTML según el Encabezado de solicitud "Tipo de contenido".

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; 
    } 

} 
Cuestiones relacionadas