Tengo un método que está anotado de la siguiente manera:
/**
* Provide a list of all accounts.
*/
// TODO 02: Complete this method. Add annotations to respond
// to GET /accounts and return a List<Account> to be converted.
// Save your work and restart the server. You should get JSON results when accessing
// http://localhost:8080/rest-ws/app/accounts
@RequestMapping(value="/orders", method=RequestMethod.GET)
public @ResponseBody List<Account> accountSummary() {
return accountManager.getAllAccounts();
}
Entonces sé que por esta anotación:
@RequestMapping(value="/orders", method=RequestMethod.GET)
este método maneja las solicitudes GET HTTP realizadas al recurso representado por la URL / pedidos .
Este método llama a un objeto DAO que devuelve una lista .
donde Cuenta representa a un usuario en el sistema y tiene algunos campos que representan a este usuario, algo como:
public class Account {
@Id
@Column(name = "ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long entityId;
@Column(name = "NUMBER")
private String number;
@Column(name = "NAME")
private String name;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = "ACCOUNT_ID")
private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();
...............................
...............................
...............................
}
Mi pregunta es: ¿Cómo funciona exactamente la @ResponseBody
anotación?
Está situado antes del List<Account>
objeto devuelto, así que creo que se refiere a esta Lista. La documentación del curso establece que esta anotación tiene la función de:
asegúrese de que el resultado se escriba en la respuesta HTTP mediante un convertidor de mensajes HTTP (en lugar de una vista MVC).
Y también leyendo sobre la documentación oficial de Spring: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html
parece que toma el List<Account>
objeto y lo coloca en el Http Response
. ¿Es esto correcto o lo estoy entendiendo mal?
Escrito en el comentario del accountSummary()
método anterior hay:
Debería obtener resultados JSON al acceder a http: // localhost: 8080 / rest-ws / app / accounts
Entonces, ¿qué significa esto exactamente? ¿Significa que el List<Account>
objeto devuelto por el accountSummary()
método se convierte automáticamente en JSON
formato y luego se coloca en el Http Response
? ¿O que?
Si esta afirmación es verdadera, ¿dónde se especifica que el objeto se convertirá automáticamente a JSON
formato? ¿Se adopta el formato estándar cuando @ResponseBody
se utiliza la anotación o se especifica en otro lugar?
Lo primero que hay que entender es la diferencia de arquitecturas.
En un extremo, tiene la arquitectura MVC, que se basa en su aplicación web normal, utiliza páginas web, y el navegador solicita una página:
El navegador realiza una solicitud, el controlador (@Controller) obtiene el modelo (@Entity) y crea la vista (JSP) a partir del modelo y la vista se devuelve al cliente. Esta es la arquitectura básica de la aplicación web.
En el otro extremo, tienes una arquitectura RESTful. En este caso, no hay vista. El controlador solo devuelve el modelo (o la representación del recurso, en términos más REST). El cliente puede ser una aplicación JavaScript, una aplicación de servidor Java, cualquier aplicación a la que expongamos nuestra API REST. Con esta arquitectura, el cliente decide qué hacer con este modelo. Tomemos por ejemplo Twitter. Twitter como la Web (REST) API, que permite que nuestras aplicaciones usen su API para obtener actualizaciones de estado, de modo que podamos usarlo para poner esos datos en nuestra aplicación. Esa información vendrá en algún formato como JSON.
Dicho esto, al trabajar con Spring MVC, primero se creó para manejar la arquitectura básica de la aplicación web. Existen diferentes tipos de firmas de métodos que permiten producir una vista a partir de nuestros métodos. El método podría devolver un
ModelAndView
donde lo creamos explícitamente, o hay formas implícitas en las que podemos devolver algún objeto arbitrario que se establece en los atributos del modelo. Pero de cualquier manera, en algún momento del ciclo de solicitud-respuesta, se producirá una vista.Pero cuando usamos
@ResponseBody
, estamos diciendo que no queremos que se produzca una vista. Solo queremos enviar el objeto de retorno como cuerpo, en cualquier formato que especifiquemos. No quisiéramos que fuera un objeto Java serializado (aunque es posible). Entonces, sí, debe convertirse a algún otro tipo común (este tipo normalmente se trata a través de la negociación de contenido; consulte el enlace a continuación). Honestamente, no trabajo mucho con Spring, aunque me dedico a ello aquí y allá. Normalmente, uso@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE)
para establecer el tipo de contenido, pero tal vez JSON sea el predeterminado. No me cite, pero si obtiene JSON y no ha especificado el
produces
, entonces tal vez sea el predeterminado. JSON no es el único formato. Por ejemplo, lo anterior podría enviarse fácilmente en XML, pero necesitaría tener elproduces
toMediaType.APPLICATION_XML_VALUE
y creo que debe configurarloHttpMessageConverter
para JAXB. En cuanto al JSONMappingJacksonHttpMessageConverter
configurado, cuando tenemos a Jackson en el classpath.Me tomaría un tiempo para aprender sobre la negociación de contenido . Es una parte muy importante de REST. Le ayudará a aprender sobre los diferentes formatos de respuesta y cómo asignarlos a sus métodos.
fuente
@Controller/@RestController
. Descubrí que necesito omitir de alguna manera la capa de resolución de vistas. No es tan simple porque la clase AbstractController proporciona un método que debe devolver el nombre de la vista. Hice una pregunta al respecto: stackoverflow.com/questions/41016018/… , si tiene algunas ideas sobre cómo puedo resolver mi problema, publique un comentario.Además de esto, el tipo de devolución está determinado por
Lo que la solicitud HTTP dice que quiere: en su encabezado Accept. Intente mirar la solicitud inicial para ver en qué está configurado Aceptar.
Lo que configura HttpMessageConverters Spring. Spring MVC configurará convertidores para XML (usando JAXB) y JSON si las bibliotecas de Jackson están en la ruta de clases.
Si hay una opción, elige una; en este ejemplo, resulta ser JSON.
Esto se trata en las notas del curso. Busque las notas sobre convertidores de mensajes y negociación de contenido.
fuente