miércoles, 26 de julio de 2017

Sobre Stream API en Java 8

Stream API en Java8 se utiliza para trabajar con las colecciones, escribiendo el código en el estilo funcional. Gracias a su simplicidad se ha hecho muy popular entre los programadores. Segun la descripcion oficial, la bilioteca «Java.util.stream» - nos permite hacer varias operaciones de estilo funcional con las colecciones de elementos, tales como transformaciones mapReduce, etc. Contiene las operaciones "intermedias", como Stream.map o Stream.filter, pero también las operaciones "finales" como Stream.forEach o Stream.reduce . Las operaciones "intermedias" no serán ejecutadas hasta q una operacion "final" sera llamada (Stream.map no sera ejecutado hasta Stream.reduce, tb si lo metes antes en el código). Ese comportamiento se llama LAZY.
Otra gran característica de Stream API es la paralelización de las fuentes parallelStream (). Se utiliza para mejorar el rendimiento cuando tienes q procesar grandes cantidades de datos. Las corrientes paralelas pueden acelerar la ejecución para ciertos tipos de transacciones. Yo las uso, cuando sé que la colección es demasiado grande para manejarla con «ForkJoin». Más información sobre la biblioteca ForkJoin puedes leer aqui: http://www.baeldung.com/java-fork-join.
Volvemos a nuestras ovejas y vamos a considerar un ejemplo práctico. Un ejemplo para buscar máximos y mínimos en una colección.

ArrayList testValues = new ArrayList();
testValues.add(0,15);
testValues.add(1,1);
testValues.add(2,2);
testValues.add(3,100);
testValues.add(4,50);
Optional
maxValue = testValues.stream().max(Integer::compareTo);
System.out.println("MaxValue="+maxValue);
Optional
minValue = testValues.stream().min(Integer::compareTo);
System.out.println("MinValue="+minValue); 



jueves, 13 de julio de 2017

Tutorial: servicio Spring REST y cliente AngularJS (parte 1: versión básica)

Casi todos los tutoriales que he visto en internet te hacen crear el servicio y el cliente juntos en una aplicación. Pero dime cuando lo has visto en la vida real? En una empresa normal las aplicaciones y la infraestructura de back-end están claramente separados de los de front-end. Osea q las 2 cosas casi nunca van juntas. Los clientes front-end normalmente desarrollan programadores JavaScript juntos con diseñadores Web que a veces no están ni en el mismo edificio con los de back-end.
Por eso vamos a crear el servicio y el cliente por separado:

Servicio:

Paso 1:

Abre Eclipse y crea New->Dynamic Web Project o mejor con maven (New->Maven Project). Selecciona el arquetipo maven-archetype-webapp:


Lo llamamos app-test-greeting-service y va tener una estructura siguiente:


Paso 2:

Dentro src crea un paquete hello y tres classes Java:


La clase Application será una cosa mas tonta del mundo:
package hello;

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

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Luego creamos nuestra clase de entidad para los mensajes que tendrán una id y un contenido:
package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}
Bueno, y nuestro controlador REST de toda la vida:
package hello;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();


    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}
- Ponle @RestController y no solamente @Controller, sino no va funcionar
- el counter va aumentar cada vez que clicas en "actualizar" de tu navegador web.
- el mensaje "Greeting" de la vuelta sera en formato JSON con el nombre que tu pasas como el parámetro (@RequestParam) El pom de tu proyecto será pequeño:

    4.0.0

    org.springframework
    app-rest-greeting
    0.1.0

    
        org.springframework.boot
        spring-boot-starter-parent
        1.3.0.RELEASE
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        
    

    
        1.8
    


    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


Lanzalo clicando derecho en tu proyecto y seleccionando "Run As->Java Application" y vas a ver lo siguiente:

Cliente:

Paso 1:

- En el Eclipse haz copiar y pegar de tu proyecto anterior y cambiale el nombre a app-test-greeting-client.
- Puedes eliminar todo el código Java del proyecto anterior de src/main

Paso 2:

- Crea una carpeta public para meter tu pagina web con el código Angular/HTML dentro:


- Creamos nuestra pagina web index.html que nos va mostrar el mensaje:

 
  Hello AngularJS
  
      
 
 
  
Your name: The ID is {{greeting.id}} The content is {{greeting.content}}

Si aun no sabes que es AngularJS, te explico rapidito que es lo que esta escrito:
- La pagina web de arriba es para Angular una aplicación (ng-app)
- Los bloques de la pagina que envían o reciben algo son controladores (ng-controller)
- Dale al controlador un nombre que asi lo puedes referenciar en el código Angular (ng-controller="Hello")
- Los campos para meter cosas son modeles(ng-model) y saben actualizarse (update()) cuando le das "click" (ng-click="update()") o presionas "enter" (ng-click="enter()")
- Los campos para recibir cosas se maraca con {{}} - Crea un file hello.js y pega este codigo:

function Hello($scope, $http) {
    $http.get('greeting', {data: {name: name}}).
        success(function(data) {
            $scope.greeting = data;
        });

    $scope.update = function() {
        $http.get('greeting', {params: {name: $scope.name}}).
         success(function(data) {
             $scope.greeting = data;
         });
    }
}

- La función $http.get viene ejecutado cada vez que visitamos nuestra pagina index.html
- Esta función va a la dirección (http://localhost:8080/greeting?name=Juan) y así enviando al servidor el parámetro name
- La vuelta el servidor (el mensaje Greeting en la forma JSON) metemos en una variable greeting ($scope.greeting = data)
- La pagina web HTML de arriba recibe esta variable y extracta 2 parámetros: id y content
The ID is {{greeting.id}} 
The content is {{greeting.content}} 
Lanzaremos el cliente y iremos a http://localhost:8080/index.html:


Clicamos varias veces en el botón y veremos como aumenta nuestro id. En la segunda parte haremos una aplicación mas complicada que va obtenir información desde la base datos.

lunes, 10 de julio de 2017

Como desplegar el JAR de Spring Boot en otro servidor (JBoss, Tomcat, WebSphere)

Sabemos que el lanzamiento de una aplicacion Spring Boot as muy fácil y se hace con el método main():
@SpringBootApplication
public class RestServiceDemoApplication {
   public static void main(String[] args) throws Exception 
   {
       SpringApplication.run(TuNuevaAplicacion.class, args);
   }
}
Para probar rapidito, si tu aplicación va bien - eso es mejor método: lanzas y la Spring Boot se te lanza una instancia de Tomcat automáticamente. Pero q pasa, si lo tienes q desplegarla en otro servidor? Spring Boot te genera un JAR, pero otro servidor acepta solo un WAR para las aplicaciones web. Q hacemos? Convertir JAR de Spring Boot en WAR es muy facil y asi lo puedes copiar y meter en la carpeta /webapps del servidor. - Paso 1: tienes que añadir a tu clase principal la extensión de la clase SpringBootServletInitializer
@SpringBootApplication
public class RestServiceDemoApplication extends SpringBootServletInitializer
- Paso 2: tienes que añadir una implementación de un método de la clase SpringBootServletInitializer
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
   return application.sources(RestServiceDemoApplication.class);
}
Codigo completo:
@SpringBootApplication
public class RestServiceDemoApplication extends SpringBootServletInitializer {
   @Override
   protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(RestServiceDemoApplication.class);
   }
   public static void main(String[] args) throws Exception {
      SpringApplication.run(RestServiceDemoApplication.class, args);
   }
}
- Paso 3: anadir a pom.xml el packaging
war
y la clase principal en los "properties"
com.example.restservicedemo.RestServiceDemoApplication
ahora puedes crear el package o desde Eclipse, o desde la linea de comandos: - mvn package Maven te dira, donde el WAR sera creado: normalmente hay una carpeta target en la carpeta de tu proyecto. Toma este WAR para desplegarlo en tu servidor:

lunes, 3 de julio de 2017

Tutorial: comunicación entre Java y una base de datos H2 (con ejemplos): Parte 1 - JDBC

La problemática de comunicación entre las aplicaciones Java y las bases de datos ha sido actual desde el primer año de la existencia del lenguaje Java. Hoy vamos a mirar, cómo con años ha evolucionado el método de esta comunicación haciendo una aplicación "enterprise" simple.

Principio
Tenemos una empresa que tiene unos empleadores (tabla Employee). Cadauno tiene su dirección (tabla Address). Y cadauno tiene sus proyectos en cuyos está trabajando (tabla Projects). Visto que cada proyecto puede tener varios empleadores y cada empleador puede trabajar en varios proyectos - tenemos una relación del tipo ManyToMany y eso lógicamente nos hace crear una tabla intermedia - una tabla con asociaciones entre empleadores y proyectos - la llamamos EmplProj:

EmployeeID ProjectID
1                    1
1                    2
2                    2
3                    3
4                    4

Se ve que el empleador #1 trabaja con los proyectos #1 y #2, al mismo tiempo con el proyecto #2 están trabajando el empleador #1 y el empleador #2.
El esquema relacional de nuestra base de datos: