En este tutorial se explica de forma simple la configuración básica de Spring boot + Jersey, como se puede observar este post será la parte 1, próximamente se publicarán las siguientes partes en las que se explicarán temas más avanzados sobre Spring boot + REST Jersey.

1. Configuración, para configurar spring boot es muy simple, solo se deben realizar las siguientes tareas: heredar del proyecto base de spring boot, incluir las dependencias de los módulos de spring a utilizar y configurar los plugins que se utilizarán en el proyecto.

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.4.0.RELEASE</version>
</parent>

Al heredar del proyecto padre de Spring boot se heredan las versiones definidas en esa version, de tal modo que no se deben definir las versiones en el proyecto que se desarrolla.

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-jersey</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
		<scope>provided</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
	</dependency>
</dependencies>

Como se puede observar solo se deben definir las dependencias más no las versiones, ya que estas versiones están definidas en el proyecto spring-boot-starter-parent.

<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<configuration>
				<source>1.8</source>
				<target>1.8</target>
			</configuration>
		</plugin>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

2.Una vez realizada la configuración de maven se debe crear una clase principal de nuestra aplicación, esta clase será la responsable de iniciar la aplicación e iniciar el contenedor, el contenedor default es Jetty, pero como se puede ver en las dependencias en este proyecto se utilizará Tomcat.

/**
 *
 */
package com.raidentrance;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author raidentrance
 *
 */
@SpringBootApplication
public class SprinBootSampleApplication  {
	public static void main(String[] args) throws Exception {
		SpringApplication.run(SprinBootSampleApplication.class, args);
	}

}

La pregunta más común que surge en este punto es : Si se está realizando una aplicación web ¿Por qué crear un método main en la aplicación? La respuesta es simple, la aplicación no generará un war sino que generará un fat jar, se conoce como fat jar porque contiene a demás de la aplicación, un contenedor embebido ya sea un Jetty o un Tomcat depende de como se configure, en este caso será un Tomcat. en futuros posts se explicará como desplegarlo en un ambiente productivo

3. Escribiendo el web service rest, para realizar un servicio REST con Spring solo se deben utilizar las anotaciones de Jersey y anotar las clases con @Component para agregarla al contexto de Spring.

/**
 *
 */
package com.raidentrance.resource;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.springframework.stereotype.Component;

/**
 * @author raidentrance
 *
 */

@Component
@Path("/users")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {

	@GET
	public String getUsers() {
	 return "{\"username\":\"raidentrance\"}";
	}

}

A continuación se describe el significado de cada una de las anotaciones utilizadas:

  • @Component : Utilizada para indicar que la clase UserResource se encontrará en el contexto de Spring.
  • @Path(«users») : Utilizada para definir el endpoint a través del cual se accederá al servicio, es posible colocar otra anotación a nivel de método para definir endpoints más complejos.
  • @Produces(MediaType.APPLICATION_JSON) / @Consumes(MediaType.APPLICATION_JSON) : Indican que los endpoints registrados en esa clase consumirán y producirán JSON, por este motivo lo que devuelve el método  getUsers() se encuentra en formato JSON, es posible colocar estas anotaciones a nivel de método para modificar el comportamiento dependiendo del método.

4. Registrando el servicio, una vez que se cuenta con el servicio y con Spring boot configurado, lo único que resta es registrar el servicio en Jersey, para hacer esto se debe crear una clase que registre los servicios a utilizar en la aplicación.

/**
 *
 */
package com.raidentrance.config;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;

import com.raidentrance.resource.UserResource;

/**
 * @author raidentrance
 *
 */
@Component
public class JerseyConfig extends ResourceConfig {
	public JerseyConfig() {
		 register(UserResource.class);
	}
}

Esta clase no se debe invocar desde ningún otro lado de la aplicación, con el hecho de estar anotada con @Component y heredar de ResourceConfig Spring sabrá que la debe utilizar para registrar los servicios.

5. Ejecutando y probando, para probar la aplicación lo único que se debe hacer es ejecutar la clase SprinBootSampleApplication como una aplicación de escritorio, si se desea ejecutar el jar utilizando:

 java -jar target/nombre-del-jar.jar

Salida:

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.0.RELEASE)

2016-09-02 11:23:28.005 INFO 20231 --- [ restartedMain] c.r.SprinBootSampleApplication : Starting SprinBootSampleApplication on m-C02RV1WXG8WP.local with PID 20231 (/Users/maagapi/Documents/Github/spring-boot-example/target/classes started by maagapi in /Users/maagapi/Documents/Github/spring-boot-example)
2016-09-02 11:23:28.008 INFO 20231 --- [ restartedMain] c.r.SprinBootSampleApplication : No active profile set, falling back to default profiles: default
2016-09-02 11:23:28.064 INFO 20231 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@53294542: startup date [Fri Sep 02 11:23:28 CDT 2016]; root of context hierarchy
2016-09-02 11:23:28.646 INFO 20231 --- [ restartedMain] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2016-09-02 11:23:29.000 INFO 20231 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-09-02 11:23:29.012 INFO 20231 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-09-02 11:23:29.013 INFO 20231 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.4
2016-09-02 11:23:29.075 INFO 20231 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-09-02 11:23:29.075 INFO 20231 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1013 ms
2016-09-02 11:23:29.260 INFO 20231 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-09-02 11:23:29.261 INFO 20231 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2016-09-02 11:23:29.261 INFO 20231 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'com.raidentrance.config.JerseyConfig' to [/*]
2016-09-02 11:23:29.441 INFO 20231 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2016-09-02 11:23:29.469 INFO 20231 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-09-02 11:23:29.510 INFO 20231 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-09-02 11:23:29.513 INFO 20231 --- [ restartedMain] c.r.SprinBootSampleApplication : Started SprinBootSampleApplication in 2.206 seconds (JVM running for 2.542)

Para probar el servicio se debe acceder a la URL http://localhost:8080/users

En las siguientes partes de este post se explicará lo siguiente: agregar logs, configurar spring security, spring data, despliegue en producción y manejo de errores.

Puedes encontrar el código completo del ejemplo en el siguiente enlace: https://github.com/raidentrance/spring-boot-example

Autor:

Autor: Alejandro Agapito Bautista

Twitter: @raidentrance

Contacto:raidentrance@gmail.com