Spring + Maven: creando un proyecto

maven java logo

Continuando con esta serie de ejemplos usando Spring y Maven veremos cómo crear un proyecto desde la línea de comandos. En está ocasión mostraremos algunas variables del entorno y un mensaje.

Crear proyecto:

mvn archetype:generate -DgroupId=com.codemonkey -DartifactId=SimpleApp -
DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Ahora dentro del directorio (simpleapp) teclear:

mvn eclipse:eclipse

Para poder abrir el proyecto con Eclipse IDE.

Agregar esto en el pom.xml:

<!-- Spring framework -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
    <version>2.5.6</version>
  </dependency> 

  

Teclear de nuevo:

mvn eclipse:eclipse

Creamos una clase:

Saludar.java

package com.codemonkey.component;

import org.springframework.stereotype.Component;

import static java.lang.System.out;

@Component
public class Saludar{
	public void diHola(){
    	out.println("Programando con Spring Framework");
    	out.println("Usuario: "+System.getProperty("user.name"));
    	out.println("Home: "+System.getProperty("user.home"));
    	out.println("Directorio: "+System.getProperty("user.dir"));
    	out.println("Arch OS: "+System.getProperty("os.arch"));
    	out.println("Name OS: "+System.getProperty("os.name"));
    	out.println("OS version: "+System.getProperty("os.version"));
    	out.println("Java home: "+System.getProperty("java.home"));
    	out.println("Java vendor: "+System.getProperty("java.vendor.url"));
    	out.println("Java version: "+System.getProperty("java.version"));
    }

    public String decirAdios(){
        return "Arrivaderci!";
    }

}

Clase principal:
SimpleAppApplication.java

package com.codemonkey;

/**
* mvn compile
* mvn package
* cd target
* java -jar SimpleApp-0.0.1-SNAPSHOT.jar
*/

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.codemonkey.component.Saludar;

@SpringBootApplication
public class SimpleAppApplication {

	public static void main(String[] args) {
		mockDemoD();
	}

	public static void mockDemoA(String[] argum){
		ApplicationContext context = SpringApplication.run(SimpleAppApplication.class, argum);
		Saludar saludar = (Saludar)context.getBean("saludar");
		saludar.diHola();
	}
}

Compilar:

mvn compile

Ejecutar:

mvn exec:java -Dexec.mainClass="com.codemonkey.SimpleApp"

Crear JAR:

mvn package

Ejecutar:

java -jar SimpleApp-0.0.1-SNAPSHOT.jar

 Links:
https://codemonkeyjunior.wordpress.com/2018/11/07/spring-maven/

Advertisements

Spring Boot + Vue JS

cafe-151346_640

En esta ocasión veremos como usar Vue JS en una aplicación Spring Boot.

Creamos nuestra tabla contacto.

contacto.sql

CREATE DATABASE IF NOT EXISTS prueba;

USE prueba;

CREATE TABLE IF NOT EXISTS contacto(id int auto_increment primary key, nombre varchar(100), telefono varchar(12) not null, fecha datetime);

Insertamos algunos valores.

INSERT INTO contacto (nombre,telefono,fecha) VALUES ('Daniel Alcantara','76662323', now()), ('Tomas Torres','5559099', now());

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.codemonkey</groupId>
	<artifactId>servidor</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>servidor</name>
	<description>Servidor de servicio web</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web-services</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</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-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-web-services</artifactId>
		</dependency>
		<dependency>
		    <groupId>wsdl4j</groupId>
	        <artifactId>wsdl4j</artifactId>
		</dependency>

        <dependency>
		   <groupId>org.slf4j</groupId>
           <artifactId>slf4j-api</artifactId>
           <version>1.6.1</version>
		</dependency>

        <dependency>
		  <groupId>org.springframework.data</groupId>
		  <artifactId>spring-data-rest-core</artifactId>
		  <version>3.1.1.RELEASE</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.6</version>
    <executions>
      <execution>
        <id>xjc</id>
        <goals>
          <goal>xjc</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <schemaDirectory>${project.basedir}/src/main/resources</schemaDirectory>
      <outputDirectory>${project.basedir}/src/main/java/com/codemonkey/clases</outputDirectory>
      <clearOutputDir>false</clearOutputDir>
    </configuration>
  </plugin>


		</plugins>
	</build>


</project>

Nuestro archivo application.yml tendrá el siguiente aspecto:
application.yml

#BANNER
banner:
   charset: UTF-8
   location: banner.txt

spring:
   thymeleaf:
      cache: false
      check-template: true
      check-template-location: true
      content-type: text/html
      enabled: true
      encoding: UTF-8
      suffix: .html
   jpa:
      generate-ddl: true
      database-platform: org.hibernate.dialect.MySQL5Dialect
      show-sql: false
      hibernate.ddl-auto: update
      hibernate.naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
   servlet.multipart.max-file-size: 128KB
   servlet.multipart.max-request-size: 128KB
   http.multipart.enabled: false
   datasource.url: jdbc:mysql://localhost:3306/prueba?useSSL=false
   datasource.driver-class-name: com.mysql.jdbc.Driver
   datasource.username: root
   datasource.password: root

Nuestra entidad Contacto.java. Usaremos la librería lombok para ahorrar escribir código.

package com.codemonkey.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Setter;
import lombok.ToString;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.GenerationType;
import javax.persistence.Table;


@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Table(name="contacto")
@Entity(name="Contacto")
public class Contacto implements java.io.Serializable{
    private static final long serialVersionUID = 7526472295622776147L;
    
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Getter @Setter public int id;
    @Column(name="nombre")
    @Getter @Setter public String nombre;
    @Column(name="telefono")
    @Getter @Setter public String telefono; 
    @Column(name="fecha")
    @Getter @Setter public LocalDate fecha;
}

Ahora un repositorio.
ContactoCrudRepository.java

package com.codemonkey.repository;

import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import com.codemonkey.model.Contacto;

public interface ContactoCrudRepository extends CrudRepository{

    @Query(value="SELECT * FROM contacto ORDER BY id ",nativeQuery=true)
    public List<Contacto> getAllContactos(); 
}

Es necesario notar que dentro de la anotación @Query podemos declarar una consulta SQL nativa. En est caso SELECT * FROM contacto ORDER BY id.

El siguiente paso es declarar un servicio y su implementación.

package com.codemonkey.service;

import java.util.List;
import com.codemonkey.model.Contacto;

public interface ContactoCrudService{
    public List<Contacto> getAllContactos();
}

La implementación de este servicio sería el siguiente:

package com.codemonkey.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;

import com.codemonkey.repository.ContactoCrudRepository;
import com.codemonkey.service.ContactoCrudService;
import com.codemonkey.model.Contacto;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Service("contactoCrudService")
public class ContactoCrudServiceImpl implements ContactoCrudService{
    private final Logger LOGGER = LoggerFactory.getLogger(ContactoCrudServiceImpl.class);

    @Autowired
    private ContactoCrudRepository contactoCrudRepository;
    
    @Override
    public List<Contacto&gt getAllContactos(){
        LOGGER.info("--Has entrado a getAllContactos");
        return contactoCrudRepository.getAllContactos();
    }
} 

Creamos el ContactoRestController.java

package com.codemonkey.controller;

//import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import com.codemonkey.model.Contacto;
import com.codemonkey.service.ContactoCrudService;


@RestController
@RequestMapping("/rest")
public class ContactoRestController{

    private final Logger LOGGER = LoggerFactory.getLogger(ContactoRestController.class);
       
    //@Qualifier("contactoService")
    @Autowired
    private ContactoCrudService contactoCrudService;

    //http:localhost:8080/rest/contactosRest
    @GetMapping("/contactosRest")
    public List<Contacto&gt getAllContactos(){
        LOGGER.info("--Has entrado a http://localhost:8080/rest/contactosRest");
        return contactoCrudService.getAllContactos();
    }
}

Ahora una vista. Antes deberíamos aclarar que debemos la importar tres archivos necesarios para trabajar con Vue JS.

<!--Vue JS -->
<script
  src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js">
</script>
<script
  src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js">
</script>
<!--axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

contactosVueJS.html

<!DOCTYPE html>
<html lang="es"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <title>Contactos</title>
        <script type="text/javascript" src="/js/funciones.js"></script>
        <link rel="stylesheet" type="text/css" media="all" href="css/estilos.css" th:href="@{css/estilos.css}" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
  <!--Vue JS -->
<script
  src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js">
</script>
<script
  src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js">
</script>
<!--axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    </head>
    <body>
<div class="jumbotron text-center">
   <h1 align="center" class="bg-dark text-white">Contactos</h1><br/>
   <a href="#" th:href="@{/proyecto/home}" title="regreso">Home</a>
</div>

<div id="my_app">    
    <div class="table-responsive">
        <table class="table table-dark table-striped" style="font-family: Chakra Petch">
            <thead >
                <tr>
                    <th>Nombre</th>
                    <th>Teléfono</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="data in contactos">
                    <td> <p contenteditable="true">{{ data.nombre }} </p></td>
                    <td><p contenteditable="true">{{ data.telefono }}</p></td>
                    
                </tr>
            </tbody>
        </table></div>

</div>

<script>
var my_app = new Vue({
    el:'#my_app',
    data(){
        return {
            contactos:[]
        };
    },
    methods:{
        getContactos(){
            axios
            .get('http://localhost:8080/rest/contactosRest')
            .then((data) => {
                this.contactos = data.data
            });
        }
    },
    mounted(){
        this.getContactos()
    },
});
</script>
</body>
</html>

En el fragmento de código javascript podemos analizar lo siguiente

//Creamos un objeto tipo Vue y sus atributos, en este caso el id será "my_app"
   var my_app = new Vue({
    el:'#my_app',
    data(){
        return {
            contactos:[]
        };
    },   //Declaramos un método getContactos() que hace una invocación
// al método get(URL) de axios, en esa URL esta nuestro servicio rest
    methods:{
        getContactos(){
            axios
            .get('http://localhost:8080/rest/contactosRest')
            .then((data) => {
                this.contactos = data.data
            });
        }
    },
    mounted(){
        this.getContactos()
    },
});

Dentro del fragmento HTML se puede observar lo siguiente:

<div id="my_app">    
    <div class="table-responsive">
        <table class="table table-dark table-striped" style="font-family: Chakra Petch">
            <thead >
                <tr>
                    <th>Nombre</th>
                    <th>Teléfono</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="data in contactos">
                    <td> <p contenteditable="true">{{ data.nombre }} </p></td>
                    <td><p contenteditable="true">{{ data.telefono }}</p></td>
                    
                </tr>
            </tbody>
        </table></div>

</div>

En esta parte accedemos a los atributos nombre y telefono:

{{ data.nombre }}
{{ data.telefono }}

¡Feliz código!

Git para incipientes

c2cd9-seleccic3b3n_008

En esta ocasión veremos cómo clonar un repositorio desde Bitbucket (antes deberías crear una cuenta).

Creamos un directorio, yo lo he denominado testRepositorios.

$ mkdir testRepositorios && cd testRepositorios

$ pwd
$ git --version

Iniciamos nuestro git.

$ git init

Se te pedirá agregar tu nombre de usuario y correo, son los mismos que tu cuenta en Bitucket.

$ git config --global user.name "TuNombreDeUsuario"

$ git config --global user.email "TuEmail"

Clonamos el repo.

$ git clone https://Super_Usser@bitbucket.org/Super_Usser/simpleapp.git

Nos ubicamos en la carpeta y listamos el contenido.

$ cd simpleapp && ls

Ver estado.

$ git status

Agregar algún archivo y vemos el estado.

$ touch nuevo.txt

$ git status

Agregar nuevo archivo.

$ git add nuevo.txt

Comentar el cambio.

$ git commit -m "Se ha agregado un nuevo archivo."

Ver de nuevo el estado.

$ git status

Enviar cambio.

$ git push

En caso que desde el repositorio raíz exista un cambio debemos obtener antes ese cambio y agregarlo a nuestro “clon”.

$ git pull

 
¡Feliz código!

 

 

Spring + Maven

user-154199_640

En está serie de post hemos visto como crear y ejecutar aplicaciones Java y Spring con Maven. He aguí otro ejemplo más.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.codemonkey</groupId>
  <artifactId>Inicio</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Inicio</name>
  <url>http://maven.apache.org</url>
  <properties>
    <spring.version>3.0.5.RELEASE</spring.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  <!-- Spring 3 dependencies -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <!-- JavaConfig need this library -->
  <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
  </dependency>
  </dependencies>
</project>

HelloWorld.java

package com.codemonkey.interfaces;

public interface HelloWorld{
    void printHelloWorld(String msg);
}

HelloWorldImpl.java

package com.codemonkey.clases;

import com.codemonkey.interfaces.HelloWorld;

public class HelloWorldImpl implements HelloWorld{

    public void printHelloWorld(String msg) {
        System.out.println("Hola : " + msg);
    }
}

AppConfig.java

package com.codemonkey.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.codemonkey.interfaces.HelloWorld;
import com.codemonkey.clases.HelloWorldImpl;

@Configuration
public class AppConfig {

    @Bean(name="helloBean")
    public HelloWorld helloWorld() {
        return new HelloWorldImpl();
    }
}

App.java

package com.codemonkey;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.codemonkey.interfaces.HelloWorld;
import com.codemonkey.config.AppConfig;

public class App {
    public static void main( String[] args ){
        helloWorld();
    }

    public static void helloWorld(){
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        HelloWorld obj = (HelloWorld) context.getBean("helloBean");
        obj.printHelloWorld("Hola, mundo!!!");
    }
}

Ejecutar:

mvn exec:java -Dexec.mainClass="com.codemonkey.App"

Visto en: http://www.java2s.com/Tutorials/Java/Spring/0035__Spring_3_JavaConfig.htm

Crear proyecto Java con Maven

mug-524103_1920

Generar proyecto.

mvn archetype:generate -DgroupId=com.codemonkey -DartifactId=Inicio -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Ubicarnos en el proyecto.

cd Inicio

Compatibilidad con eclipse.

mvn eclipse:eclipse

Archivos generados.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.codemonkey</groupId>
  <artifactId>Inicio</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Inicio</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
    <version>2.5.6</version>
  </dependency>   
  </dependencies>
</project>

App.java


package com.codemonkey;

/**
 * Hola mundo!
 *
 */
public class App {
    public static void main( String[] args ){
        System.out.println( "Hola mundo!" );
    }
}

Compilar.

mvn compile

Ejecutar.

mvn exec:java -Dexec.mainClass="com.codemonkey.App"  

Grails … un ejemplo

ec564-shomecode4

En este post crearemos un mini sistema para la gestión de tickets de soporte técnico.

¿Qué necesitamos?

  1. Tener instalado el JDK 8
  2. Tener instalado Grails
  3. Tener una BD (usaremos PostgreSQL en este ejemplo)

Tenemos los departamentos o áreas ).

areas

Se levantan los tickets

tickets

El encargado de dar soporte técnico responderá a las peticiones.

respuesta

Analizamos las relaciones.

Un Departamento tiene muchos Ticket(s)

Un Ticket pertenece a un Departamento

Una Respuesta pertenece a un Ticket

Tendremos en total tres clases:

  1. Departamento.groovy
  2. Ticket.groovy
  3. Respuesta.groovy

c2cd9-seleccic3b3n_008

Primer paso: crear el proyecto

$ grails create-app crud-app

Segundo paso: ubicarnos en la carpeta del proyecto creado

$ cd crud-app

Tercer paso: crear las tres clases

$ grails create-domain-class com.codemonkey.model.Departamento
$ grails create-domain-class com.codemonkey.model.Ticket
$ grails create-domain-class com.codemonkey.model.Respuesta

Departamento.groovy

package com.codemonkey.model

class Departamento {
    int iddepartamento
    String nombre
    String responsable

    static constraints = {
        nombre(blank: false)
        responsable(blank: false)
    }

    //Un Departamento tiene muchos Tickets
    static hasMany = [tickets: Ticket]

    String toString(){
        "**Departamento\nId:"+id+"\nNombre:"+nombre+"\nResponsable:"+responsable
    }
}

Ticket.groovy

package com.codemonkey.model

class Ticket {
    int idticket
    Date fecha
    String asunto
    String descripcion

    static constraints = {
        asunto(blank: false)
        descripcion(black: false)
    }

    //Una Tickets pertenece a un Departamento
    static belongsTo = [departamentos: Departamento]

    String toString(){
        "**Ticket\nId:"+id+"\nFecha:"+fecha+"\nAsunto:"+asunto+"\nDescripcion:"+descripcion
    }
}

Respuesta.groovy

package com.codemonkey.model

class Respuesta {
    int idrespuesta
    boolean solucionado
    String descripcion

    static constraints = {
        descripcion(blank: false)
    }

    //Una Respuesta pertenece a un Tickets
    static belongsTo = [tickets: Ticket]

    String toString(){
        String result = solucionado == true? "Solucionado" : "En espera"
        "**Respuesta\nId:"+id+"\nDescripcion:"+descripcion+"\nSolucionado:"+result
    }
}

Cuarto paso: configurar las dependencias necesarias y la conexión a la BD

build.gradle

 buildscript {
repositories {
mavenLocal()
maven { url “https://repo.grails.org/grails/core&#8221; }
}
dependencies {
classpath “org.grails:grails-gradle-plugin:$grailsVersion”
classpath “org.grails.plugins:hibernate5:${gormVersion-“.RELEASE”}”
classpath “com.bertramlabs.plugins:asset-pipeline-gradle:2.14.8”
}
}

version “0.1”
group “crud.app”

apply plugin:”eclipse”
apply plugin:”idea”
apply plugin:”war”
apply plugin:”org.grails.grails-web”
apply plugin:”asset-pipeline”
apply plugin:”org.grails.grails-gsp”

repositories {
mavenLocal()
maven { url “https://repo.grails.org/grails/core&#8221; }
}

dependencies {
runtime(‘org.postgresql:postgresql’)

compile “org.springframework.boot:spring-boot-starter-logging”
compile “org.springframework.boot:spring-boot-autoconfigure”
compile “org.grails:grails-core”
compile “org.springframework.boot:spring-boot-starter-actuator”
compile “org.springframework.boot:spring-boot-starter-tomcat”
compile “org.grails:grails-web-boot”
compile “org.grails:grails-logging”
compile “org.grails:grails-plugin-rest”
compile “org.grails:grails-plugin-databinding”
compile “org.grails:grails-plugin-i18n”
compile “org.grails:grails-plugin-services”
compile “org.grails:grails-plugin-url-mappings”
compile “org.grails:grails-plugin-interceptors”
compile “org.grails.plugins:cache”
compile “org.grails.plugins:async”
compile “org.grails.plugins:scaffolding”
compile “org.grails.plugins:events”
compile “org.grails.plugins:hibernate5”
compile “org.hibernate:hibernate-core:5.1.5.Final”
compile “org.grails.plugins:gsp”
console “org.grails:grails-console”
profile “org.grails.profiles:web”
runtime “org.glassfish.web:el-impl:2.1.2-b03”
runtime “com.h2database:h2”
runtime “org.apache.tomcat:tomcat-jdbc”
runtime “com.bertramlabs.plugins:asset-pipeline-grails:2.14.8”
testCompile “org.grails:grails-gorm-testing-support”
testCompile “org.grails:grails-web-testing-support”
testCompile “org.grails.plugins:geb:1.1.2”
testRuntime “org.seleniumhq.selenium:selenium-chrome-driver:2.47.1”
testRuntime “org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1”
testRuntime “net.sourceforge.htmlunit:htmlunit:2.18”
}

bootRun {
jvmArgs(‘-Dspring.output.ansi.enabled=always’)
addResources = true
String springProfilesActive = ‘spring.profiles.active’
systemProperty springProfilesActive, System.getProperty(springProfilesActive)
}

tasks.withType(Test) {
systemProperty “geb.env”, System.getProperty(‘geb.env’)
systemProperty “geb.build.reportsDir”, reporting.file(“geb/integrationTest”)
systemProperty “webdriver.chrome.driver”, System.getProperty(‘webdriver.chrome.driver’)
systemProperty “webdriver.gecko.driver”, System.getProperty(‘webdriver.gecko.driver’)
}

assets {
minifyJs = true
minifyCss = true
}

configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 10, ‘minutes’
}

project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each {
println ‘ [Dependencias] ‘
println ‘artifact: ‘+it.name
println ‘referencia: ‘+it.file
println ‘**************************’
}

application.yml

---
grails:
    profile: web
    codegen:
        defaultPackage: crud.app
    gorm:
        reactor:
            # Whether to translate GORM events into Reactor events
            # Disabled by default for performance reasons
            events: false
info:
    app:
        name: '@info.app.name@'
        version: '@info.app.version@'
        grailsVersion: '@info.app.grailsVersion@'
spring:
    main:
        banner-mode: "off"
    groovy:
        template:
            check-template-location: false

# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false
    jmx:
        enabled: true

---
grails:
    mime:
        disable:
            accept:
                header:
                    userAgents:
                        - Gecko
                        - WebKit
                        - Presto
                        - Trident
        types:
            all: '*/*'
            atom: application/atom+xml
            css: text/css
            csv: text/csv
            form: application/x-www-form-urlencoded
            html:
              - text/html
              - application/xhtml+xml
            js: text/javascript
            json:
              - application/json
              - text/json
            multipartForm: multipart/form-data
            pdf: application/pdf
            rss: application/rss+xml
            text: text/plain
            hal:
              - application/hal+json
              - application/hal+xml
            xml:
              - text/xml
              - application/xml
    urlmapping:
        cache:
            maxsize: 1000
    controllers:
        defaultScope: singleton
    converters:
        encoding: UTF-8
    views:
        default:
            codec: html
        gsp:
            encoding: UTF-8
            htmlcodec: xml
            codecs:
                expression: html
                scriptlets: html
                taglib: none
                staticparts: none
endpoints:
    jmx:
        unique-names: true

---
hibernate:
    cache:
        queries: false
        use_second_level_cache: false
        use_query_cache: false
dataSource:
    pooled: true
    jmxExport: true
    driverClassName: org.postgresql.Driver # org.h2.Driver
    username: postgres #sa
    password: 5432 #''

environments:
    development:
        dataSource:
            dbCreate: update
            url: jdbc:postgresql://localhost:5432/inventario #jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    test:
        dataSource:
            dbCreate: update
            url: jdbc:postgresql://localhost:5432/inventario #jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    production:
        dataSource:
            dbCreate: none
            url: jdbc:postgresql://localhost:5432/inventario #jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
            properties:
                jmxEnabled: true
                initialSize: 5
                maxActive: 50
                minIdle: 5
                maxIdle: 25
                maxWait: 10000
                maxAge: 600000
                timeBetweenEvictionRunsMillis: 5000
                minEvictableIdleTimeMillis: 60000
                validationQuery: SELECT 1
                validationQueryTimeout: 3
                validationInterval: 15000
                testOnBorrow: true
                testWhileIdle: true
                testOnReturn: false
                jdbcInterceptors: ConnectionState
                defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED

Quinto paso: generar las vistas, etc.

$ grails generate-all "*"

Sexto paso: ejecutar aplicación

$ grails run-app

Abrir el navegador en: http://127.0.0.1:8080/

Es todo por el momento.

Un vistazo a Grails Framework

cropped-hunger-413685_960_7201.jpg

¿Qué es Grails Framework?

  1. Es un framework para desarrollo de aplicaciones web.
  2. Permite usar Java y Groovy.
  3. Funciona bajo el paradigma Modelo-Vista-Controlador.
  4. Se considera la versión de Ruby on Rails de Java.

Si usas SDKMAN! puedes instalarlo así:

$ sdk install grails

Comprobamos la versión instalada:

$ grails -version

Para crear un proyecto tecleamos lo siguiente:

$ grails create-app my-app

Nos colocamos en la carpeta creada:

$ cd my-app

Creamos un controller:

$ grails create-controller com.codemonkey.controller.Hola

La clase creada (Hola.groovy) se encontrará en:

grails-app/controller/com/codemonkey/controller

Hola.groovy

package com.codemonkey.controller

class Hola{

def index(){

render "Hola, amigos !!"

}

}

Para ejecutar la aplicación:

$ grails run-app

Abrimos nuestro navegador en:

http://127.0.0.1:8080/my-app

Por el momento es todo. En posteriores post escribiremos una aplicación más compleja.

Links

http://codigoprogramacion.com/articulos/programacionweb/ique-es-grails-framework-de-desarrollo-web.html#.Wz1_4-ZG3Dc

https://grails.org/