Tips, Soluciones y Novedades en Tecnología

22/02/2016

Anotaciones en Java Reflection



Asi como las clases y palabras reservadas en java, existe un tipo especial para definir  como anotación, es allí donde uno puede crear sus propias anotaciones para usos específicos.











Las anotaciones es una especificación en cual busca simplificar el código usado en java, así mismo junto con Java Reflexion, nos brinda la potencia de poder tener control total de las anotaciones que implementemos.



Las anotaciones son amplia mente utilizadas por la mayorías de frameworks java, por ejemplo Spring Framework con sus @Autowired, Hibernate también hace uso de las anotaciones para simplificar el mapeo de los objetos, evitando escribir en archivos xml.



Vamos a crear nuestra propia anotación y vamos a ver también como podemos usarlo, un caso tipico seria en una validación.



No necesitamos dependencias ya que es una implementan nativa de java.








 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
*
* @author Reynaldo Claros
* @email reyiclaros@gmail.com
*/
@Documented
@Target(ElementType.FIELD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnotacion {

String mensahe() default "";

}







Esta anotación lo que va hacer es capturar el valor que tiene asignado el campo de la clase que definiremos.



La clase MyClase lo definimos.








 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

/**
*
* @author Reynaldo Claros
* @email reyiclaros@gmail.com
*/
public class MyClase {

@MyAnotacion(mensahe = "Campo name")
private String name;
@MyAnotacion(mensahe = "Campo dni")
private String dni;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDni() {
return dni;
}

public void setDni(String dni) {
this.dni = dni;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}





Después solo tenemos que instanciar la clase asignarle los parámetros y enviarlo a un método para su procesamiento.








 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

public static void main(String[] args) {
MyClase clase = new MyClase();
clase.setName("Java for Developers");
clase.setDni("19283282222");
clase.setAge(2);
/**
* Procesamos
*/
procesandoAnotacion(clase);
}

private static void procesandoAnotacion(Object obj) {
Class cl = obj.getClass();
try {
for (Field field : cl.getDeclaredFields()) {
field.setAccessible(true);
try {
for (Annotation anno : field.getDeclaredAnnotations()) {
if (anno.annotationType() == MyAnotacion.class) {
MyAnotacion myanotacion = (MyAnotacion) anno;
System.out.println("Mensaje de la anotacion : " + myanotacion.mensahe());
System.out.println("Nombre del campo : " + field.getName());
System.out.println("Valor del campo : " + field.get(obj).toString());
System.out.println("----------------------------");
}
}
} catch (IllegalAccessException | IllegalArgumentException | SecurityException e) {
System.out.println(e.getMessage());
}
}
} catch (SecurityException | IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}





El resultado es:








1
2
3
4
5
6
7
8

Mensaje de la anotacion : Campo name
Nombre del campo : name
Valor del campo : Java for Developers
----------------------------
Mensaje de la anotacion : Campo dni
Nombre del campo : dni
Valor del campo : 19283282222
----------------------------







Como podéis ver, las anotaciones son una poderosa herramienta, cuando queremos hacer nuestros propios validadores y otros cometidos.



Saludos cordiales.

Fechas con JodaTime



Una de las cosas con las que he tenido que trabajar son las fechas, hacer operaciones con la librería Date del API de java, digamos que no es del todo amigable y fácil de hacerlo si queremos encontrar diferencias exactas en manejo de fechas.







Vamos a ver una librería que nos facilita mucho ese trabajo, hagamos los escenarios para el cual nos puede servir:






  • Encontrar Nro de días entre fechas

  • Diferencia entre fecha mayor y menor

  • Encontrar nro de meses entre dos fechas

  • Determinar intervalos entre 2 fechas. etc






Los que hace la librería JodaTime es tomar como base una fecha de partida (1970), a aparir de allí, hacer la contabilización y puede hacer todo tipos de operaciones lo que respecta a manejo de fechas.








Para incluirlo en nuestro proyecto solo basta con declarar en nuestro pom.xml o bajar directamente el .JAR (Lib) y agregarlo manualmente a nuestra librería.








1
2
3
4
5
6
7

<!-- JODA TIME -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.2</version>
</dependency>
<!-- /JODA TIME-->





Hagamos un ejemplo para determinar los periodos entre 2 fechas, el código para dicha operación seria el siguiente.










 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

private static void calcularNroPeriodos(Date fecha1, Date fecha2) {
if (fecha1 != null && fecha2 != null) {
/**
* Parseamo al formato de fecha que maneja JodaTime
*/

DateTime myfecha1 = new DateTime(fecha1);
DateTime myfecha2 = new DateTime(fecha2);

/**
* Asignamos un instante es decir desde 1970 a la fecha actual
* registrado.
*/
Instant instanteFecha1 = myfecha1.toInstant();
Instant instanteFecha2 = myfecha2.toInstant();
/**
* Determino el intervalo, pero para ello debo saber que la fecha1
* sea mayor a la fecha2, para poder aplicar la regla. Con el
* instante de fecha ya se puede determinar que fecha es mayor
*/
if (instanteFecha1.getMillis() > instanteFecha2.getMillis()) {
Interval intervalTask = new Interval(instanteFecha1, instanteFecha2);

/**
* Y por ultimo defino el periodo
*/
Period periodo = intervalTask.toPeriod(PeriodType.dayTime());

/**
* Pueden explorar todos los metodos que tiene Periodo
*/
System.out.println("Nro de Años entre las fechas :" + periodo.getYears());
System.out.println("Nro de Meses entre las fechas :" + periodo.getMonths());
System.out.println("Nro de Dias entre las fechas :" + periodo.getDays());
}
}
}





Mas ejemplos en la pagina oficial del proyecto: http://www.joda.org/joda-time/



Saludos cordiales.



Plantillas en Netbeans



Muchos developers usan Netbeans IDE, como favorito, pero muchos también no aprovechan al máximo las herramientas y plugins que trae netbeans para facilitarle al developer en su trabajo.





Cuando creamos clases, interfaces, etc, muchas veces replicamos y tenemos que copiar de otra clase todo el contenido para poder avanzar.



Netbean IDE, tiene un modulo que se encarga de administrar plantillas, es decir puedes modificar las ya existentes y también puedes crear tus propias plantillas, según tu propósito.







En la imagen se puede apreciar una serie de plantillas por tipo y lenguajes, hay una variedad de plantillas disponibles para agilizar nuestros desarrollos, por ejemplo yo tengo un grupo de plantillas que me facilitan mi desarrollo.









Para acceder los hacemos: Tools -> Templates 

Al hacer click en Java Class, se mostrar la siguiente Plantilla.








 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<#assign licenseFirst = "/*">
<#assign licensePrefix = " * ">
<#assign licenseLast = " */">
<#include "${project.licensePath}">

<#if package?? && package != "">
package ${package};

</#if>
/**
*
* @author ${user}

 */
public class ${name} {

}





Por eso cuando le dan agregar una clase siempre te sale con esa estructura.



Entonces como podéis ver allí pueden agregar todo el código que necesiten para no tener que estar repitiendo, pero ojo, tienen que crear su propia plantilla por ejemplo ClaseDAO.

A continuación podemos ver mi plantilla personalizada, ustedes tienen que hacerlo según su propósito








 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

<#assign licenseFirst = "/*">
<#assign licensePrefix = " * ">
<#assign licenseLast = " */">
<#include "${project.licensePath}">

<#if package?? && package != "">
package ${package};

</#if>
/**
*
* @author ${user}
* @email reyiclaros@gmail.com
* @Company Java for developers
* @website www.claros-java.blogspot.com
*/
public class ${name} {

private static String getNameClass(){
return this.getClass.getSimpleName();
}

}





Saludos cordiales.



Plantillas con Freemarker








Cuando programamos, aveces necesitamos utilizar Plantillas, como por ejemplo correos electrónicos, los que estan comenzando suelen usar un  String para concatenar el cuerpo y descripciones del asunto y si lo han estado usando pues a partir de leer este post, van a comenzar a utilizar una  plantilla para ese cometido.









Una de las librerías que mas difundidas para el uso de plantillas es Freemarker ahora un proyecto mas de la Apache Software Fundation.



A continuación vamos hacer un ejemplo del uso de esta motor de plantilla, haremos una plantilla para enviar un correo electrónico, es decir el body del correo.



 TemplateEmail.ftl






<html>
<head>
<title>Notificacion de Java for developers</title>
</head>
<body>
<h1>Estimado :${username} </h1>
<p>
<h2>Asunto : ${subjet}</h2>
<hr>
<i>
<a href="http://claros-java.blogspot.com">Java for Developers</a>
<br>
</i>
</body>
</html>




Primero necesitamos obtener las dependencias del repositorio de maven, para los que no usan maven lo pueden bajar directamente aquí: Jar Freemarker



Una vez descargado los descomprimen adjuntan como JAR externo a su libreria de su proyecto.



Continuando agregamos la dependencia a nuestro pom.xml


 




<!-- TEMPLATE-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>







Con esto ya tenemos el .jar en nuestro proyecto, ya sea por maven o adjuntando el .jar manualmente.

el código para un HTML parseado es el siguiente:






 public static String loadTemplate() throws Exception {
String templateString = "";
Writer out = new StringWriter();
try {
Template template = getConfig().getTemplate("TemplateEmail.ftl");
Map<String, Object> data = new HashMap<>();
data.put("username", "Reynaldo Claros");
data.put("subjet", "Ejemplo de Plantilla con Freemarker");
template.process(data, out);
templateString = out.toString();
out.close();
} catch (java.io.IOException | freemarker.template.TemplateException e) {
log.error("error ({})", e.getMessage());
throw new IOException(e.getMessage());
}
return templateString;
}




Una vez ejecutado, la cadena que se obtiene es la siguiente:






<html>
<head>
<title>Notificacion Java for Developers</title>
</head>
<body>
<h1>Estimado :Reynaldo Claros </h1>
<p>
<h2>Asunto : Ejemplo de Plantilla con Freemarker</h2>
<hr>
<i>
<a href="http://claros-java.blogspot.com">Java for Developers</a>
<br>
</i>
</body>
</html>




Saludos cordiales.


Multiples SpringContexts en web.xml



Cuando tenemos una aplicación bastante grande, en la configuración de Spring, este caso voy a ponerlos un escenario que que servirá de propósito general cuando necesitemos cargar archivos de spring automáticamente cuando se inicia la aplicación














La imagen muestra una aplicación con muchos archivos de configuración, una forma optima administrarlos es agrupándolos por carpetas, pero necesitamos decirle a spring que cargue todos los archivos que hemos definido.





A continuación vamos a ver como podemos pasarlo mediante parámetro a spring,  definiendo  en el web.xml de nuestra aplicación, ya que esta es la que se inicia al iniciar la aplicación, una vez iniciada spring sera capaz  de leer todos los SpringContexts, de una determinada carpeta, así no sera necesario especificar en el web.xml archivo por archivo, si no que mediante un comodín (*) y spring  cargara todos los archivos con la expresión similar.








<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/springfiles/applicationContext*.xml
</param-value>
</context-param>






Saludos cordiales.