Usar Spring REST CORS es muy habitual hoy en día ya que la mayoría de peticiones a servicios REST que se realizan es utilizando algún tipo de tecnología Javascript y por lo tanto utilizando AJAX. Crear un servicio REST con Spring Framework es muy sencillo hoy en día ya que es suficiente con crear una clase anotada con @RestController . Vamos a verlo utilizando Spring Boot , para ello necesitaremos instalar las dependencias de Web.
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
Una vez instaladas estas dependencias el siguiente paso es construirnos un Controlador de tipo REST que Spring nos provee por defecto con la típica url de /mensaje.
package com.arquitecturajava.rest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HolaRESTController { @GetMapping("/mensaje") public String mensaje() { return "hola desde spring rest"; } }
Creado el controlador nos será suficiente con arrancar la aplicación de Spring Boot y solicitar la url.
El servicio REST nos responde sin ningún problema . Ahora bien esto se debe a que realizamos una invocación directa y no vía JavaScript . Si intentamos solicitar esta url con JavaScript utilizando jQuery nos encontraremos con un problema de Cross Origin Resource Sharing (CORS) que nos impide el acceso.
<html> <head> <script type="text/javascript" src="jquery-3.3.1.min.js"> </script> <script type="text/javascript"> $(document).ready(function() { $.get("http://localhost:8080/mensaje",function(datos) { console.log(datos); }) }) </script> </head> <body> </html>
Si cargamos esta página veremos rapidamente un error en la consola que nos restringe el acceso debido a que estamos realizando una petición ajax desde JavaScript y estas peticiones por defecto están limitadas a ficheros JavaScript que nos descarguemos desde el mismo servidor.
Si nosotros este fichero le cargamos desde un navegador directamente con file:// nos aparecerá el siguiente error:
Spring REST CORS
El recurso esta por defecto bloqueado para peticiones que no hagan desde localhost , caso de nuestra petición que se realiza desde un fichero directamente . Para solventar este problema es suficiente con modificar el servicio de Spring y añadir una cabecera @CrossOrigin para que nos permite el acceso desde otras ubicaciones.
En este caso vamos a ser generalistas y permitir acceder al recurso desde cualquier lugar.
package com.arquitecturajava.rest; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @CrossOrigin(origins = "*", methods= {RequestMethod.GET,RequestMethod.POST}) public class HolaRESTController { @GetMapping("/mensaje") public String mensaje() { return "hola desde spring rest"; } }
Volvemos a cargar el servidor y ahora si podremos acceder al mensaje almacenado en la url:
Recordemos que siempre que tengamos recursos REST y queramos acceder a ellos debemos usar Spring REST CORS y abrir el acceso remoto sino por defecto los datos de nuestros servicios no estarán accesibles.
muchas gracias, es de gran ayuda, tengo un problema un poco mas complejo, al intentar consumir los recursos de angular cli, compilando con buid –prod el bloqueo persiste, pero si lo consumo en modo de de Angular si funciona.
gracias de antenano.
https://stackoverflow.com/questions/47426721/angular-cli-change-rest-api-url-on-build
Muchísimas gracias, depués de mucho tiempo de estar buscando una solución, tu solución me ayudó, el problema es que estába tratando de colocar el header en el origen A, pero tenía que colocarlo en el servidor B.
de nada 🙂
Me sirvio mucho, gracias!!!
de nada 🙂
Muchas gracias amigo!!, estoy tratando de implementar vue junto axios para consumir la api en spring boot y me acabas de salvar la vida jaja buen post sigue aportando contenido de calidad a la comunidad!
gracias, me alegro de haberte ayudado:)
Hola muy buena tu explicacion, yo estoy trabajando en angular y spring boot pero me sale un error
Access to XMLHttpRequest at ‘https://’ from origin ‘https://’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
1 Failed to load resource: net::ERR_FAILED
Gracias.
Da la sensación que te falta una cabecera en el recurso y no puedes acceder a el
Hola, funcional igual para un desarrollo más grande con más módulos etc, tengo que agregar un @Bean en el main para una configuración global ??
Si voy a utilizar métodos como put, delete , también tengo que agregarlos, o basta con los dos principales ??
Tendras que agregar lo que corresponda, hay a haces que alguíen solo tiene permisos para buscar e insertar pero no borrar
Hola,
A pesar de que implemento esta solución como se detalla en el articulo, spring security me rechaza la petición. ¿Habría alguna solución para ello?
Saludos,
Celeste.
Depende mucho de la versión de Spring etc , cada una tiene sus cosas . Revisa en algún otro sitio una versión más cercana a la tuya
Debes revisar porque se está rechazando, utiliza las herramientas de desarrollo del navegador y vee en la consola de errores cual es el motivo.
Muchas gracias por la ilustración
de nada 🙂
Siempre con las mejores píldoras.
me alegro que te sea util 🙂
Estuve peleando con esto del CORS por un buen tiempo, muchas gracias por mostrarnos esta solución.
de nada 🙂
Muchas gracias la explicacion, esto da solucion a un problema que me tuvo toda una tarde buscando respuesta, me quedo todo muy claro acerca de como funciona CORS.
de nada 🙂
Muy buena publicación, me gustó mucho toda la explicación tan clara y el ejemplo sencillo para abarcar la explicación de cómo funciona lo de CORS, así como el código y diagramas me ayudaron mucho. Me resolvió el problema que tenía.
Muchas gracias!!!
de nada 🙂
hola, tengo este inconveniente
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (default-cli) on project MicroservicioGuiado: Command execution failed. Process exited with an error: 1 (Exit value: 1) -> [Help 1]
To see the full stack trace of the errors, re-run Maven with the -e switch.
Re-run Maven using the -X switch to enable full debug logging.
For more information about the errors and possible solutions, please read the following articles:
Muy buenos post, el otro día de tanto seguirlos termine comprando uno de tus cursos y son de igual calidad. Espero que sigas mucho tiempo así, hay poco contenido de esta calidad en español.
¿Te consulto saldrá una nueva versión de tus cursos de Spring con la versión 5?
Saludos desde Argentina.