martes, marzo 11, 2014

Hola mundo con JAXB

Esta ves regreso con un pequeño ejemplo para utilizar JAXB, una herramienta muy útil para manejar documentos XML. Esta se encarga de transformar una clase Java a XML y a la inversa. sin mas empiezo con el ejemplo. 

En este ejemplo utilizare 2 objetos: "usuario" y dentro de este un bean "empresa".


import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Empresa {
 private int id;
 private String nombre;
 
 public int getId() {
  return id;
 }
 @XmlAttribute
 public void setId(int id) {
  this.id = id;
 }
 public String getNombre() {
  return nombre;
 }
 @XmlElement
 public void setNombre(String nombre) {
  this.nombre = nombre;
 }
}


import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Usuario {
 
 
 private String nombre; 
 private String apellido; 
 private int id;
 private Empresa empresa;

 public String getNombre() {
  return nombre;
 }
 @XmlElement
 public void setNombre(String nombre) {
  this.nombre = nombre;
 }
 public String getApellido() {
  return apellido;
 }
 @XmlElement
 public void setApellido(String apellido) {
  this.apellido = apellido;
 }
 public int getId() {
  return id;
 }
 @XmlAttribute
 public void setId(int id) {
  this.id = id;
 }
 public Empresa getEmpresa() {
  return empresa;
 }
 @XmlElement
 public void setEmpresa(Empresa empresa) {
  this.empresa = empresa;
 }
 
}

Se puede apreciar que estoy utilizando 3 anotaciones diferentes:

  •  @XmlRootElement .- esta anotación indica que la clase sera un bloque xml.
  •  @XmlElement .- esta anotación indica que sera un elemento del bloque xml.
  •  @XmlAttribute .- indica que la variable sera un atributo distintivo del bloque xml.
Ahora toca el turno de la clase encargada de convertir los beans de java a bloques xml.


import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

//clase que hara el marshalling
public class JavaToXML {
 
 public void marshalling( String rutaArchivo , Usuario bean ){
  try {
import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

//clase que hara el marshalling
public class JavaToXML {
 
 public void marshalling( String rutaArchivo , Usuario bean ){
  try {
   //creamos un archivo
   File file = new File( rutaArchivo );
  
   //generamos una instancia de nuestro bean principal
   JAXBContext jaxbContext;  
   jaxbContext = JAXBContext.newInstance(Usuario.class);
   
   //preparamos la formacion del xml
   Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
   //indicamos que el resultado xml debe estar con formato, es decir: identado y no en un renglon
   jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  
   //indicamos los destinos del xml resultante, en este caso el archivo y la consola
   jaxbMarshaller.marshal( bean , file);
   jaxbMarshaller.marshal( bean , System.out);
   
  } catch (JAXBException e) {
   e.printStackTrace();
  }
 }
 
 public static void main( String args [] ){
  JavaToXML ejemplo = new JavaToXML();
  
  Usuario bean = new Usuario();
  bean.setNombre( "perla" );
  bean.setApellido( "leal" );
  bean.setId( 12 );
  
  Empresa beanE = new Empresa();
  beanE.setId( 2 );
  beanE.setNombre( "Java-limos" );
  bean.setEmpresa( beanE );
  
  String rutaArchivo = "C:\\myEjemplo.xml";
  
  ejemplo.marshalling( rutaArchivo , bean );
 }
 
}

si ejecutamos el siguiente código obtendremos un archivo como el siguiente:




    leal
    
        Java-limos
    
    perla

proseguimos a crear la clase encargada de convertir el xml en beans de java



import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

//Unmarshaller
public class XMLToJava {

 public void unmarshalling( String rutaArchivo ){
  try {
   //indicamos el archivo xml
   File file = new File( rutaArchivo );
   
   //creamos una instancia del bean principal
   JAXBContext jaxbContext = JAXBContext.newInstance(Usuario.class);
   
   //preparamos el convertidor xml a java
   Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
   
   //extraemos la informacion
   Usuario usuario = (Usuario) jaxbUnmarshaller.unmarshal(file);

   System.out.println( "nombre: " + usuario.getNombre() );
   System.out.println( "apellido: " + usuario.getApellido() );
   System.out.println( "id: " + usuario.getId() );
   System.out.println( "empresa: " + usuario.getEmpresa().getNombre() );
   
  } catch (JAXBException e) {
   e.printStackTrace();
  }
 }
 
 public static void main( String args [] ){
  XMLToJava ejemplo = new XMLToJava();
  
  String rutaArchivo = "C:\\myEjemplo.xml";
  ejemplo.unmarshalling( rutaArchivo );
 }
}

Como se puede ver es un código muy sencillo, basta con leer un poco la documentación y ponerse a jugar con el para poder crear xml mas complejos.

saludos. 

Encriptación utilizando el algoritmo AES Actualizado

Hace ya un tiempo escribí una entrada sobre la encriptación AES, y he de aceptar que cometí 2 errores en el código por tanto vuelvo a subir la clase principal y esta ves con el código en forma continua haciendo incapie en las diferencias contra el original, de este modo espero solventar los inconvenientes que causo el código anterior.

finalmente les comento que la clase AESKey utilizada en la entrada anterior queda intacta saludos.
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESEncriptacion {

 private AESKey aesKey;
 private final String ALGORITMO = "AES";
 private final int LONGITUD = 128;
 private final String CODIFICACION = "UTF-8";

 public AESEncriptacion(AESKey aesKey) throws Exception {  
  this.aesKey = aesKey;
 }
  
 public AESKey generaKey() throws Exception {
   KeyGenerator kgen = KeyGenerator.getInstance(ALGORITMO);
   kgen.init(LONGITUD);
   SecretKey skey = kgen.generateKey(); 
   AESKey aesKey = new AESKey();
   aesKey.setEncoded(HexToString(skey.getEncoded()));
   //originalmente estava (metida de pata)
   // aesKey.setEncoded(StringtoHex(skey.getEncoded()));
   return aesKey;
 }
 
 public String encripta(String cadena) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, 
 IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {  
    byte[] raw = StringToHex(aesKey.getEncoded());
    SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITMO);
    Cipher cipher = Cipher.getInstance(ALGORITMO);
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(cadena.getBytes(CODIFICACION));
    String encriptado = HexToString(encrypted);
    return encriptado;
 }
 
 private String HexToString(byte[] arregloEncriptado) {
   String textoEncriptado = "";
   for (int i = 0; i < arregloEncriptado.length; i++) {
     int aux = arregloEncriptado[i] & 0xff;
     if (aux < 16) {
      textoEncriptado = textoEncriptado.concat("0");
     }
     textoEncriptado = textoEncriptado.concat(Integer.toHexString(aux));
   }
   return textoEncriptado;
 }
 
 private byte[] StringToHex(String encriptado) {
   byte[] enBytes = new byte[encriptado.length() / 2];
   for (int i = 0; i < enBytes.length; i++) {
     int index = i * 2;
     String aux = encriptado.substring(index, index + 2);
     int v = Integer.parseInt(aux, 16);
     enBytes[i] = (byte) v;
   }
   return enBytes;
 }
 
 public String desencriptar(String encriptado) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
   UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException {
   byte[] raw = StringToHex(aesKey.getEncoded());
   SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITMO);
   Cipher cipher = Cipher.getInstance(ALGORITMO);  
   cipher.init(Cipher.DECRYPT_MODE, skeySpec);
   byte[] original = cipher.doFinal(StringToHex(encriptado));
   String originalString = new String(original);
   return originalString;
 }
 
 public static void main(String args[]) throws Exception {
   AESKey aesKey = new AESKey();
     
   AESEncriptacion tmp = new AESEncriptacion(aesKey);
   //originalmente estava, error nuevamente
   //AESEncriptacion tmp = new AESEncriptacion();
   aesKey = tmp.generaKey();
    
   AESEncriptacion ejemplo = new AESEncriptacion(aesKey);
   
   String encriptado = ejemplo.encripta("123456789012345678");
   String desencriptado = ejemplo.desencriptar(encriptado);
   System.out.println(encriptado);
   System.out.println(desencriptado);
   System.out.println("***************************************************");
   encriptado = ejemplo.encripta("esto es un segundo ejemplo");
   desencriptado = ejemplo.desencriptar(encriptado);
   System.out.println(encriptado);
   System.out.println(desencriptado);
 }
}