La anotación Spring RestController es una anotación de conveniencia que está anotada con @Controller y @ResponseBody
. Esta anotación se aplica a una clase para marcarla como un controlador de solicitudes. La anotación Spring RestController se utiliza para crear servicios web RESTful utilizando Spring MVC. Spring RestController se encarga de mapear los datos de la solicitud al método de controlador de solicitud definido. Una vez que se genera el cuerpo de la respuesta a partir del método del controlador, lo convierte en una respuesta JSON o XML.
Ejemplo de Spring RestController
Veamos cómo podemos usar RestController fácilmente para crear un servicio web REST en Spring. Reutilizaremos la implementación del Repositorio de Spring y crearemos un servicio web RESTful. Crearemos una aplicación web independiente y no usaremos Spring Boot aquí. También expondremos nuestras API para admitir tanto JSON como XML en la solicitud y la respuesta. La siguiente imagen muestra la estructura final de nuestro proyecto. Los modelos y las clases de Repositorio ya se proporcionan en el tutorial del Repositorio de Spring. Aquí nos centraremos más en la implementación de RestController.
Dependencias de Maven para Spring RestController
Echemos un vistazo a las dependencias requeridas para crear nuestro proyecto de ejemplo de Spring RestController.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- Jackson for REST JSON Support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<!-- JAXB for XML Response, needed to explicitly define from Java 9 onwards -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
Necesitamos las bibliotecas de Spring MVC, Jackson y JAXB para admitir tanto las solicitudes como las respuestas XML y JSON de nuestro servicio web REST. Nuestro archivo web.xml se utiliza para configurar DispatcherServlet de Spring MVC como el controlador frontal. Veamos ahora el archivo de contexto de Spring.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<context:component-scan
base-package="com.journaldev.spring" />
<beans:bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
<beans:bean id="xmlMessageConverter"
class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
<beans:bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter" />
<beans:ref bean="xmlMessageConverter" />
</beans:list>
</beans:property>
</beans:bean>
</beans:beans>
La parte más importante son los beans jsonMessageConverter
y xmlMessageConverter
definidos y establecidos en la propiedad messageConverters
de RequestMappingHandlerAdapter
. Eso es todo lo que se necesita para decirle a Spring que queremos que nuestra aplicación admita tanto JSON como XML, y estos son los beans que se utilizarán para la transformación.
Clase Spring RestController
Aquí está la implementación de nuestra clase Spring RestController.
package com.journaldev.spring.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.journaldev.spring.model.Employee;
import com.journaldev.spring.repository.EmployeeRepository;
@RestController
public class EmployeeRestController {
@Autowired
private EmployeeRepository repository;
@GetMapping("/rest/employee/get/{id}")
public Employee getEmployeeByID(@PathVariable("id") int id) {
return repository.retrieve(id);
}
@GetMapping("/rest/employee/getAll")
//Devolver una lista es compatible solo con una respuesta JSON
//Si quieres XML, entonces agrega una clase contenedora como elemento XML raíz, por ejemplo EmployeeList
public List getAllEmployees() {
return repository.getAll();
}
@PostMapping("/rest/employee/create")
public Employee createEmployee(@RequestBody Employee emp) {
repository.store(emp);
return emp;
}
@GetMapping("/rest/employee/search/{name}")
public Employee getEmployeeByName(@PathVariable("name") String name) {
return repository.search(name);
}
@DeleteMapping("/rest/employee/delete/{id}")
public Employee deleteEmployeeByID(@PathVariable("id") int id) {
return repository.delete(id);
}
}
Ten en cuenta que aquí solo hemos definido nuestras API REST, toda la lógica comercial es parte de la clase Repository. Si nuestro método devuelve una lista o un array, entonces Spring solo admitirá una respuesta JSON porque el elemento raíz de XML no puede ser anónimo, pero JSON sí puede. Si deseas admitir la devolución de una lista como XML, entonces tendrás que crear una clase envolvente para contener esta lista y devolverla. En algunos de los métodos, esperamos un objeto Employee como la solicitud, Spring se encargará de analizar el cuerpo de la solicitud y convertirlo al objeto Employee para estos métodos. De manera similar, devolvemos un objeto Employee como el Cuerpo de Respuesta, nuevamente Spring se encargará de convertirlo a una respuesta JSON/XML.
Encabezados de Solicitud Accept y Content-Type
Hemos configurado nuestra aplicación REST para trabajar tanto con XML como con JSON. Entonces, ¿cómo sabrá si la solicitud es XML o JSON? Y si la respuesta debe enviarse en formato JSON o XML. Aquí es donde se utilizan los encabezados de Solicitud Accept
y Content-Type
. Content-Type: Define el tipo de contenido en el cuerpo de la solicitud, si su valor es “application/xml”, entonces Spring tratará el cuerpo de la solicitud como un documento XML. Si su valor es “application/json”, entonces el cuerpo de la solicitud se trata como JSON. Accept: Define el tipo de contenido que el cliente espera como respuesta. Si su valor es “application/xml”, se enviará una respuesta XML. Si su valor es “application/json”, se enviará una respuesta JSON.
Prueba del controlador Spring Rest
Nuestra aplicación está lista para ser probada, la he desplegado en Tomcat-9 y la estoy probando con Postman. A continuación se presentan los resultados de las pruebas con la explicación correspondiente.
Respuesta JSON del controlador Spring Rest
Es una solicitud GET simple, el punto importante a tener en cuenta es el valor del encabezado “Accept”.
Respuesta XML del controlador Spring Rest
Cuando cambiamos el valor del encabezado “Accept” a “application/xml”, obtenemos una respuesta XML.
Obtener lista del controlador Spring Rest
Intentemos llamar al API para obtener la lista de empleados. Estamos obteniendo una lista de elementos en JSON con un elemento raíz anónimo.
Dado que XML no admite un elemento raíz anónimo, estamos obteniendo un mensaje de excepción.
Spring RestController POST
Spring RestController POST con solicitud y respuesta JSON Spring RestController POST con cuerpo de solicitud JSON
Spring RestController POST con solicitud JSON y respuesta XML
Spring RestController DELETE
Resumen
El RestController de Spring nos ayuda a centrarnos en la lógica empresarial al encargarse de todo el trabajo tedioso para crear APIs de servicios web REST.
Puedes descargar el proyecto completo desde nuestro Repositorio en GitHub.
Source:
https://www.digitalocean.com/community/tutorials/spring-restcontroller