2011-09-12 29 views
27

que he visto ejemplos en los que un controlador devuelve una cadena (que indica la vista)controladores Spring MVC Tipo de retorno

@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET) 
public String findOwner(@PathVariable String ownerId, Model model) { 
    Owner owner = ownerService.findOwner(ownerId); 
    model.addAttribute("owner", owner); 
    return "displayOwner" 
} 

Y también ver ejemplos en los que un controlador devuelve una "ModelAndView" tipo de objeto

public ModelAndView helloWorld() { 
    ModelAndView mav = new ModelAndView(); 
    mav.setViewName("helloWorld"); 
    mav.addObject("message", "Hello World!"); 
    return mav; 
} 

¿Cuál es la diferencia entre los dos y cuál debo usar? Porque de cualquier forma puedo resolver mi punto de vista.

+0

la versión de MVC primavera estamos hablando? –

+0

Aquí está la respuesta: https://stackoverflow.com/questions/29365833/what-are-valid-return-types-of-a-spring-mvc-controller-method/29366138#29366138 – Rajeev

Respuesta

15

Si estamos hablando de MVC 3, entonces, ambos son correctos. Pero el regreso directo de ModelAndView es a la vieja usanza y más verbal.

Si devuelve solo una cadena (sin @ResponseBody que es otra cosa), esta cadena se trata como el nombre de la vista y Spring lo presiona para ver los resolutores, por lo que no tiene que preocuparse (al menos mientras están escribiendo controladores), qué tipo de renderizador usará (permita que sea jsp o velocity, no importa). Solo propagas la instancia Model y devuelve una pista sobre qué hacer con ella a continuación. El objeto apropiado ModelAndView se hace más tarde internamente por cadena.

Generalmente, el resorte 3 le da más flexibilidad con argumentos y tipos de devolución (vea la sección Defining @RequestMapping handler methods en Spring documentaton).

+1

En el nuevo enfoque de MVC 3 (devolviendo un 'String'), ¿cómo es que la instancia' Model' abre camino en la vista? En el controlador usamos 'model.addAttribute (..)' para agregar atributos pero en última instancia solo se devuelve 'String', entonces, ¿cómo sabe el resolvedor de vistas sobre el objeto' Model'? ¡Gracias! – user2490003

+0

Creo que es algún tipo de inyección de dependencia hecha por RequestMapping (es decir, el modelo se lo da el resolver), pero para ser sincero, no estoy seguro, ya que no tuve contacto con Spring durante los últimos 5 años ^^ –

1

Si está utilizando un lenguaje de plantilla como freemarker o velocidad para crear la respuesta, puede devolver el ModelAndView.

Si desea devolver un json/xml o una cadena como respuesta (p. Ej .: solicitudes ajax), puede utilizar el primer método. Creo que debería ser public @ResponseBody String findOwner(@PathVariable String ownerId, Model model), debe agregar una anotación llamada @ResponseBody para indicar que el valor devuelto se debe convertir como texto de respuesta. El uso de @ResponseBody le permitirá usar bibliotecas como Jackson o JaxB para crear respuestas json/xml, respectivamente.

Estos valores devueltos se convertirán utilizando messageConverters registrado con AnnotationMethodHandlerAdapter.

Ref: http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/

+1

Te falta el punto. Si definió 'view resolve' apropiado, la cadena devuelta será tratada como nombre para ver (jsp, template, etc.). '@ ResponseBody' no tiene nada que ver con eso. –

+0

@AdamJurczyk entonces, ¿cómo puedo usar '@ ResponseBody' (quiero devolver JSON para una llamada ajax) si ya he definido' view resolver'? Gracias – MyTitle

6

En Spring MVC, debe devolver ModelAndView si desea procesar la página JSP

Por ejemplo:

@RequestMapping(value="/index.html", method=RequestMethod.GET) 
    public ModelAndView indexView(){ 
     ModelAndView mv = new ModelAndView("index"); 
     return mv; 
    }  

esta función devolverá index.jsp cuando esté golpeando /index.html

Además puede devolver cualquier objeto JSON o XML usando @ResponseBody anotación y serializador.

Por ejemplo:

@RequestMapping(value="/getStudent.do",method=RequestMethod.POST) 
    @ResponseBody 
    public List<Student> getStudent(@RequestParam("studentId") String id){ 
     List<Student> students = daoService.getStudent(id); 
     return students; 
    } 

En este ejemplo va Lista de regreso si lo JSON en el caso y ha habilitado Jackson serializador. A fin de permitir que se necesita añadir lo siguiente a su XML de Spring:

<context:annotation-config/> 

y el propio Serializador:

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean> 
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
<property name="messageConverters"> 
    <list> 
    <ref bean="jacksonMessageConverter"/> 
    </list> 
</property> 
</bean> 

espero que ayude.

+2

No es necesario crear y devolver MAV directamente.Además de esto, si está utilizando 'context: annotation-config' no tiene que poner el serializador a mano, se hace automáticamente si' jackson' está en el classpath. –

+0

Ejemplo perfecto y simple que es muy útil. – Tastybrownies

17

Es la misma lógica, pero no es la misma versión de la primavera.

El objeto ModelAndView es la forma de manejo y vistas de la primavera 2.x. En el ejemplo que proporcionó, el objeto modelandview cargará la vista "helloWorld" (dependiendo de su motor de plantillas podría ser helloWorld.jsp, o helloWorld.html, ...) con un "mensaje" de datos en el modelo.

La otra forma es la manera de la primavera 3.x. Podrías haber escrito exactamente el mismo ejemplo que tu helloworld.

@RequestMapping(value="/helloWorld", method=RequestMethod.GET) 
public String helloWorld(Model model) { 
    model.addAttribute("message", "Hello World!"); 
    return "helloWorld"; 
} 

El modelo se rellena automáticamente bajo pedido.

Y podemos simplificar esta notación ya que el mapeo url "helloWorld" es directamente el nombre de la vista.

@RequestMapping(value="/helloWorld", method=RequestMethod.GET) 
public void helloWorld(Model model) { 
    model.addAttribute("message", "Hello World!"); 
} 

la vista helloWorld se cargará automaticamente

5

Volviendo ModelAndView o una cadena hace el mismo trabajo. Se resuelve en una vista (una página jsp) y proporciona un objeto modelo para representar en la vista. Si devuelve una cadena, el resorte se resuelve internamente en una vista usando viewResolver, crea un objeto ModelAndView y lo devuelve. El regreso del objeto ModelAndView es de la versión anterior. Puede hacer cualquiera de estos según su conveniencia.

Tener un vistazo a este question

También montón de respuestas apuntan a @RequestBody. No está exactamente relacionado con tu pregunta. Pero tenga en cuenta que convertirá su objeto en función del tipo de contenido utilizando convertidores disponibles y el resultado será parte del cuerpo del documento.

1
public String findOwner(@PathVariable String ownerId, Model model) { 
    Owner owner = ownerService.findOwner(ownerId); 
    model.addAttribute("owner", owner); 
    return "displayOwner" 
}      

en este método el tipo de retorno es String y añadiendo Modelo como un parámetro para añadir un valor con el modelo añadiremos como

modelparam.addAttribute("obj",value); 

y volver a la displayowner a JSP como por visión resolutor

public ModelAndView helloWorld() { 
    ModelAndView mav = new ModelAndView(); 
    mav.setViewName("helloWorld"); 
    mav.addObject("message", "Hello World!"); 
    return mav; 
} 

en este método el tipo de retorno es ModelAndView por lo que volverá el modelo y aquí el MAV es el objeto de ModelAndView por lo que aquí debe anuncio d como

model.addObject("object","value"); 

aquí la nombredevista se devuelve a helloworld.jsp según el ViewResolver

Cuestiones relacionadas