Mostrando entradas con la etiqueta misMétodos(). Mostrar todas las entradas
Mostrando entradas con la etiqueta misMétodos(). Mostrar todas las entradas

[Métodos] Serializar y Deserializar objetos con Java


[Métodos] Serializar y Deserializar objetos con Java



La serialización y deserialización son dos procesos utilizados en programación para convertir datos como texto o incluso un objeto de una clase, a un formato de código binario para almacenarlo o transmitirlo, y luego revertir ese proceso en otro momento o lugar para recuperar los datos originales.

Tomemos como ejemplo la sigueinte clase Persona

public class Persona implements Serializable {
    private static final long serialVersionUID = 1L; // Identificador de versión para la serialización
    private String nombre;
    private int edad;
    private String ciudad;

    // CONSTRUCTORES
    // GETTERS y SETTERS
}


Es una simple clase en java que implementa la interfaz Serializable, de la cual cobra sentido el atributo serialVersionUID ya este número de versión nos indicará a la hora de deserializar si la clase ha sufrido algún cambio o modificación.
El siguiente ejemplo, muestra un método main que:
  • Instancia un objeto de la clase Persona
  • Serializa el objeto y lo guarda en un archivo, misma ubicación donde se está ejecutando, bajo el nombre de "persona.ser"
  • Por último, este fragmento de Deserialización pudiera estar en otro lado, pero hace lo propio deserializando un archivo "persona.ser", en la misma ubicación que la ejecución y lo lleva a un objeto Persona

    public static void main(String[] args) {
        // Crear una instancia de Persona
        Persona persona = new Persona("Darío", 35, "Buenos Aires");

        // Serialización
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("persona.ser"))) {
            oos.writeObject(persona);
            System.out.println("Persona serializada correctamente.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Deserialización
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("persona.ser"))) {
            Persona personaDeserializada = (Persona) ois.readObject();
            System.out.println("Persona deserializada: " + personaDeserializada);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


Por último, nuestra propia implementación para reutilizar en métodos independientes:

Serializar


    public static void serializarObjeto(Object objeto, String ubicacion, String nombreArchivo) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(ubicacion + File.separator + nombreArchivo))) {
            oos.writeObject(objeto);
            System.out.println("Objeto serializado correctamente en: " + ubicacion + File.separator + nombreArchivo);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


Deserializar


    // Método para deserializar un objeto desde un archivo
    public static Object deserializarObjeto(String ubicacion, String nombreArchivo, String nombreClase) {
        Object objetoDeserializado = null;
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(ubicacion + File.separator + nombreArchivo))) {
            objetoDeserializado = ois.readObject();
            System.out.println("Objeto deserializado correctamente desde: " + ubicacion + File.separator + nombreArchivo);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return objetoDeserializado;
    }


Uso

    public static void main(String[] args) {
        // Ejemplo de serialización y deserialización
        Persona persona = new Persona("Dario", 35, "Buenos Aires");

        // Serialización
        serializarObjeto(persona, "ruta/del/directorio", "persona.ser");

        // Deserialización
        Persona personaDeserializada = (Persona) deserializarObjeto("ruta/del/directorio", "persona.ser", Persona.class.getName());
        System.out.println("Persona deserializada: " + personaDeserializada);
    }

[Métodos] Generar código de barras y Códigos QR - Generación de códigos QR con ZXing


Generar código de barras y Códigos QR - Generación de códigos QR con ZXing



Los códigos QR o Quick Response Code son simple códigos de barras pero en 2 dimensiones que pueden ser leidos o escaneados por una cámara, como la de un teléfono móvil.

Un código QR consiste en cuadrados negros dispuestos en una cuadrícula cuadrada sobre un fondo blanco. Existen varias variantes de códigos QR que dependen del tamaño de los símbolos, el diseño, la codificación y la estructura.

Zxing es una librería para java y android que se pronuncia "Zebra Crossing" como el cruce peatonal de Abbey Road

Procedimiento:

Hay que agregar las dependencias de zxing-core y zxing-javase a nuestro propio proyeto

Con maven

 <dependency>
  <groupId>com.google.zxing</groupId>
  <artifactId>core</artifactId>
  <version>3.4.0</version>
 </dependency>
 <dependency>
  <groupId>com.google.zxing</groupId>
  <artifactId>javase</artifactId>
  <version>3.4.0</version>
 </dependency>
 

Con gradel

 compile "com.google.zxing:core:3.4.0"
 compile 'com.google.zxing:javase:3.4.0'
 

Manualmente añadir los jar al classpath descargandolos desde maven central


El siguiente paso es poner manos al código:

  • Crear una instancia de com.google.zxing.qrcode.QRCodeWriter
  • Obtener un BitMatrix a través de encodear con el objeto QRCodeWriter, pasando el texto, el tipo de codigo y un alto y ancho
  • Por último escribir en un archivo el bitmatrix a través de método MatrixToImageWriter.writeToPath definiendo la extensión de la imagen y el path.
 private static void generateQRCodeImage(String text, int width, int height, String filePath) throws WriterException, IOException {
  QRCodeWriter qrCodeWriter = new QRCodeWriter();
  BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);

  Path path = FileSystems.getDefault().getPath(filePath);
  MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
 }
 

Asegurarse de que el directorio del parametro filePath exista, porque no lo crea y lanza una excepción.

Ejecutando en un main normal de toda la vida, obtendremos:

public static void main(String[] args) throws Exception {
    generateQRCodeImage("Hola juli =)", 350, 350, "D:/dev/qrcodes/holajuli.png");
}

Resultado

[Métodos] Generar pdf con Jasper


Crear un reporte con Jasper Report



JasperReports es una biblioteca de creación de informes que tiene la habilidad de entregar contenido enriquecido al monitor, a la impresora o a ficheros PDF, HTML, XLS, CSV y XML... y no lo digo yo sino la wikipedia

Está escrito completamente en Java, su propósito principal es ayudar a crear documentos de tipo páginas, es de bajo licencia libre GNU, por lo que es Software libre.

Una de la más notoria ventaja es el diseño de sus templates a través de una sólida interfaz visual, componentes drag and drop para realizar el template xml por nosotros, además de que con un click realiza la compilación.




iReport Designer (v5.6.0) página de descarga



Nota mental: La ultima versión del iReport es la 5.6.0 del 28-May-2014 y al parecer solo funciona con java 7 en la variable de entorno JAVA_HOME. Pueden ser cambiado desde las configuraciones en la instalación, generalmente C:\Program Files (x86)\Jaspersoft\iReport-5.5.1\etc\ireport.conf o visitando la documentación

Jaspersoft Studio Eclipse plugin página del marketplace





La manera en que trabajar es la siguiente:

  • Se escribe un template xml con la extension .jrxml
  • Se compila con el motor de jasper para generar un archivo de extension .jasper
  • Se procesa junto a una fuente de datos: Collection de java o una conexion a la base de datos para obtener un ResultSet
  • Se obtiene como resultado un reporte! :D


Procedimiento

Crear un proyeto maven saltéandose la elección del arquetipo para luego agregar las dependencias a utilizar en el pom.xml:

 <!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
 <dependency>
  <groupId>net.sf.jasperreports</groupId>
  <artifactId>jasperreports</artifactId>
  <version>6.9.0</version>
 </dependency>
 

Tras hacer esto obtendremos un error, de que no encuentra la librería de itext.jar:2.1.7.js6, el problema es que en maven central no existe esa version sino una itext.jar:2.1.7.js2 y agregando esa ya maven es feliz

 <dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>2.1.7.js2</version>
 </dependency>
 
Adicionalmente vamos a tener que declarar el repositorio jasperreports y sus librerias de terceros ya que la versión de itext que espera es la versión 2.1.7.js4 y será desde aqui donde se tomen las librerias necesarias:

 <repositories>
  <repository>
   <id>jasperreports</id>
   <url>http://jasperreports.sourceforge.net/maven2</url>
  </repository>
  <repository>
   <id>jaspersoft-third-party</id>
   <url>http://jaspersoft.artifactoryonline.com/jaspersoft/third-party-ce-artifacts/</url>
  </repository>
 </repositories>
 

Con cualquiera de las opciones disponibles para crear los jrxml, se procede a crear un reporte como a uno más le guste.



Para empezar podemos arrastrar un static text y escribir el típico hola mundo, hello world, etc.


Nota mental: Al usar el iReport 'por defecto' tiende a usar el lenguaje como groovy dando exceptions en la compilación. Hay que editarlo desde las properties del reporte en la solapa de Report Inspector o bien remover el attributo language="groovy" en etiqueta root jasperReport luego de todas las declaraciones de esquemas. Ah y de paso agregar whenNoDataType="AllSectionsNoDetail" para que no evite no generar el pdf cuando no hay un fuente de datos para completar los mismos.

El archivo creado deberá ser dejado en la carpeta src/main/resources para encontrarlo a tiro.

 public static void imprime() throws JRException, IOException {
  System.out.println("obtenemos la plantilla JRXML como un inputstream");
  InputStream template = JasperRunnable.class.getResourceAsStream("/reporte.xml");

  System.out.println("compilamos el reporte desde el stream");
  JasperReport report = JasperCompileManager.compileReport(template);

  System.out.println("obtenemos la fuente de datos");
  Map<String, Object> sourceData = new HashMap<>();

  System.out.println("llenamos el reporte en un print object, con la fuente de datos");
  JasperPrint print = JasperFillManager.fillReport(report, sourceData);

  File pdf = File.createTempFile("output.", ".pdf");
  System.out.println("Lo exportamos a " + pdf.getAbsolutePath());
  JasperExportManager.exportReportToPdfStream(print, new FileOutputStream(pdf));
 }
 
La extensión puede ser tanto xml como jrxml dado que son simple archivos de texto plano con diferentes extension, pero para el caso es indistinto.

Ejecutando esta función en la clase main obtendremos una salida de consola como la siguiente:

obtenemos la plantilla JRXML como un inputstream
compilamos el reporte desde el stream
obtenemos la fuente de datos
llenamos el reporte en un print object, con la fuente de datos
Lo exportamos a C:\Users\Imago\AppData\Local\Temp\output.5354953787413152033.pdf

Dandonos como resultado, el mas simple de los pdf:



Es lo más básico de lo más básico que puede ofrecernos jasper report, pero es sólo el inicio.

[Métodos] Crear un ejecutable (.exe) a partir de nuestro .jar de java con Launch4J


Launch4j es una herramienta para envolver aplicaciones Java distribuidas como jars in ejecutables nativos de Windows (es posible tambien envolverlos para Linux y Mac OS X)

Permite personalizar el icono de la app, crear un splash screen nativo al sistema, embeber una jre o redirigir a la pagina de descarga de Java en caso que no se encuentre disponible.

Se puede realizar con la tarea con el ejecutable como comandos de linea de consola, como tarea ant y construir con un plugin en maven.

Creando un ejecutable

Para la elaboracion del ejecutable con Launch4j necesitaremos



Principal.java

public class Principal {
    public static void main(String[] args) {
        String titulo = "Saludos con Launch4j";
        String message = "Hola juli =)";
        int messageType = JOptionPane.INFORMATION_MESSAGE;
        JOptionPane.showMessageDialog(null, message, titulo, messageType);
    }
}

Se le agrega la definicion de la clase main al plugin que genera el jar ejecutable

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/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.github.dariozubaray</groupId>
 <artifactId>saludo-joptionpane</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <name>saludosJOptionPane</name>
 <description>simple saludo desde joptionpane</description>
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
     <archive>
      <manifest>
       <mainClass>com.github.dariozubaray.Principal</mainClass>
      </manifest>
     </archive>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>

Cuando ejecutamos el goal mvn package, obtendremos nuestro jar ejecutable.




Una vez dentro de launch4j, en la solapa de basic debemos configurar

  • OutputFile: es el archivo de salida con la extension .exe
  • Jar: el jar que queremos envolver

Luego bajo JRE debemos especificar al menos la version minima de java

  • El esquema soportado por launch4j es el versionado tradicional que consta de 2 números mayor.menor(en inglés: major.minor) EJ: 1.5
  • También es válido el versionado de 3 números mayor.menor.micro, como la fase de desarrollo. EJ: 1.8.0
  • Se admite también la fase de construccion EJ: 1.7.0_51
  • A partir de java 9 es válido indicar solo el número de version. EJ: 10

Construir el envoltorio desde el icono de engranaje, lo que nos preguntará de guardar la configuración como xml

Y eso es todo, en el panel inferior debe aparecer el mensaje de 'Successfully created + la ruta completa'



Utilizando Maven plugin

Para dejar en manos de maven la creacion del ejecutable con launch4j, debemos agregar en el pom el siguiente plugin

pom.xml

<plugin>
 <groupId>com.akathist.maven.plugins.launch4j</groupId>
 <artifactId>launch4j-maven-plugin</artifactId>
 <executions>
  <execution>
   <id>l4j-clui</id>
   <phase>package</phase>
   <goals>
    <goal>launch4j</goal>
   </goals>
   <configuration>
    <headerType>gui</headerType>
    <jar>target/saludo-joptionpane-1.0.0-SNAPSHOT.jar</jar>
    <outfile>target/archivoSalidaEjecutable.exe</outfile>
    <downloadUrl>http://java.com/download</downloadUrl>
    <classPath>
     <mainClass>com.github.dariozubaray.Principal</mainClass>
    </classPath>
    <jre>
     <bundledJre64Bit>false</bundledJre64Bit>
     <bundledJreAsFallback>false</bundledJreAsFallback>
     <minVersion>1.5</minVersion>
     <jdkPreference>preferJre</jdkPreference>
     <runtimeBits>64/32</runtimeBits>
    </jre>
   </configuration>
  </execution>
 </executions>
</plugin>

Posteriormente al guardado, podemos ejecutar la fase a partir de package, aunque con maven install hace mas de lo que se necesita es más rápido. El resultado será:



Personalizandolo

Para poersonalizar al menos un poco el ejecutable podemos incluir un icono y un screensplash que es la imagen mientras se carga el programa, para ello debemos modificar la clase main para que se tarde unos segundos antes de arrancar.



Principal.java

public class Principal {
    public static void main(String[] args) {
        try {
            Thread.sleep(5000);
        } catch(InterruptedException ie) {
            ie.printStackTrace();
        }
        String titulo = "Saludos con Launch4j";
        String message = "Hola juli =)";
        int messageType = JOptionPane.INFORMATION_MESSAGE;
        JOptionPane.showMessageDialog(null, message, titulo, messageType);
    }
}

En la pestaña de basic podemos incluir la 'icon' y en la propia de 'splash', luego de habilitarla, la imagen bmp para mostrar mientras se carga la app.

[misMetodos] Expandir Variables de Entorno - expandEnvironmentVariables



Me encontrando en C# la necesidad de expandir una variable de entorno (%PUBLIC%) y ha sido recontra facil:

1
2
3
4
public static string ExpandEnviromentVariable(string source)
{
    return Environment.ExpandEnvironmentVariables(source);
}


Tratando de realizar la misma operacion en java no ha resultado tan facil, pero es posible. La estratégia resulta ser la siguiente:

  • Obtener un mapa del sistema con todas las variables de entorno System.getenv(), mi mapa resulto ser asi:
  • {
     LOCALAPPDATA=C:\Users\Desarollo-VII\AppData\Local,
     ChocolateyLastPathUpdate=marjun1911:39:562018,
     PROCESSOR_LEVEL=16,
     FP_NO_HOST_CHECK=NO,
     M2=C:\dev\apache-maven-3.2.1/bin,
     VS140COMNTOOLS=C:\ProgramFiles(x86)\MicrosoftVisualStudio14.0\Common7\Tools\,
     USERDOMAIN=DESARROLLOVI,
     LOGONSERVER=\\DESARROLLOVI,
     JAVA_HOME=C:\ProgramFiles\Java\jdk1.8.0_91,
     SESSIONNAME=Console,
     ALLUSERSPROFILE=C:\ProgramData,
     PROCESSOR_ARCHITECTURE=AMD64,
     PSModulePath=...,
     SystemDrive=C:,
     ANT_HOME=C:\dev\apache-ant-1.9.7,
     DEV_HOME=C:\dev,
     APPDATA=C:\Users\Desarollo-VII\AppData\Roaming,=A:=A:\,
     USERNAME=Desarollo-VII,
     ChocolateyInstall=C:\ProgramData\chocolatey,
     ProgramFiles(x86)=C:\ProgramFiles(x86),
     JBOSS_HOME_=C:\dev\APPsERVER\jboss-4.2.3.GA,
     CommonProgramFiles=C:\ProgramFiles\CommonFiles,
     Path=..., 
     PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC,
     OS=Windows_NT,
     COMPUTERNAME=DESARROLLOVI,
     JBOSS_HOME=C:\dev\APPsERVER\wildfly-10.1.0.Final,
     PROCESSOR_REVISION=0402,
     CommonProgramW6432=C:\ProgramFiles\CommonFiles,
     ComSpec=C:\Windows\system32\cmd.exe,
     ProgramData=C:\ProgramData,
     ProgramW6432=C:\ProgramFiles,
     HOMEPATH=\Users\Desarollo-VII,
     SystemRoot=C:\Windows,
     TEMP=C:\Users\DESARO~1\AppData\Local\Temp,
     HOMEDRIVE=C:,
     PROCESSOR_IDENTIFIER=AMD64Family16Model4Stepping2,
     USERPROFILE=C:\Users\Desarollo-VII,
     TMP=C:\Users\DESARO~1\AppData\Local\Temp,
     M2_HOME=C:\dev\apache-maven-3.2.1,
     CommonProgramFiles(x86)=C:\ProgramFiles(x86)\CommonFiles,
     ProgramFiles=C:\ProgramFiles,
     PUBLIC=C:\Users\Public,
     NUMBER_OF_PROCESSORS=3,
     windir=C:\Windows,
    }
    


  • Crear un Patter para divir la variable en 2 grupos: uno con la expresion completa y el otro sin los porcentajes (Este seria la key del mapa de variabless)
  • 1
    2
    3
    4
    5
    Pattern pattern = Pattern.compile("%(.*?)%");
    Matcher matcher = pattern.matcher(valorInicial);
    
    String grupoCeroPatronEntrePorcentajes = matcher.group(0);
    String grupoUnoPatronSinPorcentaje = matcher.group(1);
    


  • Luego con la key en la mano, se obtiene el valor del mapa
  • Por ultimo se hace un replace del grupo uno(entre porcentaje) con el value del mapa obtenido con el grupo dos





 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public static String expandEnvironmentVariables(String valorInicial) {
    String valorRetorno = null;
    Map<String, String> variablesEntorno = System.getenv();

    Pattern pattern = Pattern.compile("%(.*?)%");
    Matcher matcher = pattern.matcher(valorInicial);

    while (matcher.find()) {
        String grupoCeroPatronEntrePorcentajes = matcher.group(0);

        String grupoUnoPatronSinPorcentaje = matcher.group(1);
        String valorVariableEntorno = variablesEntorno.get(grupoUnoPatronSinPorcentaje);

        valorRetorno = valorInicial.replace(grupoCeroPatronEntrePorcentajes, valorVariableEntorno);
    }

    return valorRetorno;
}


Ejemplo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
System.out.println(expandEnvironmentVariables("%USERPROFILE%\\archivo.txt"));
System.out.println(expandEnvironmentVariables("%APPDATA%\\.minecraft"));
System.out.println(expandEnvironmentVariables("%PUBLIC%\\PepeFolder"));
System.out.println(expandEnvironmentVariables("%WINDIR%\\fonts"));
System.out.println(expandEnvironmentVariables("%JAVA_HOME%\\jre\\bin\\java.exe"));
System.out.println(expandEnvironmentVariables("%JBOSS_HOME%\\bin\\run.bat"));
System.out.println(expandEnvironmentVariables("%M2%"));
System.out.println(expandEnvironmentVariables("%ANT_HOME%"));

/* Outputs:
C:\Users\Desarollo-VII\archivo.txt
C:\Users\Desarollo-VII\AppData\Roaming\.minecraft
C:\Users\Public\PepeFolder
No se encontro la variable : %WINDIR%\fonts
C:\Program Files\Java\jdk1.8.0_91\jre\bin\java.exe
C:\dev\APPsERVER\wildfly-10.1.0.Final\bin\run.bat
C:\dev\apache-maven-3.2.1/bin
C:\dev\apache-ant-1.9.7
*/


Lo unico que habria que validar, es que el mapa no es lo mismo la key PUBLIC o public

[MisMetodos] Definir la raíz del contexto en JBoss

Se necesita crear el archvio de nombre 'jboss-web.xml' en la raiz de 'WEB-INF' con el siguiente contenido:



En mi caso el proyecto se llama auomatizacion.

<?xml version="1.0" ?>
<jboss-web>
    <context-root>/nombreDeLaAplicacion</context-root>
</jboss-web>

según la propia Documentación de Jboss (funciona para 4.2.3.GA)

atributos descripción
context-root Root context of the web-app. It defaults to the filename of the deployment without suffix .war




Traducción al español

El contexto raíz de la aplicación web. El valor predeterminado es el nombre de archivo de despliegue sin el sufijo .war

Esto permite porner el war con el nombre de version e incluso de construccion y que el nombre al que se acceda sea el mismo

[Métodos] Conocer IP donde ejecutamos Java


Para conocer nuestra ip local debemos recurrir a la clase java.net.InetAddress

Esta clase representa una dirección de protocolo de internet(IP) o bueno es lo que la documentación misma dice.

Solo basta con importar la clase, instanciar un objeto de la misma a través del método getLocalHost()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import java.net.InetAddress;
...
InetAddress ip;
try {
    ip = InetAddress.getLocalHost();
    System.out.print("ipLocal: ");
    System.out.println(ip.getHostAddress());
} catch (UnknownHostException e) {
    e.printStackTrace();
}

La salida será del estilo:
1
ipLocal: 10.0.0.157


También InetAddress nos permitirá conocer el nombre de la pc y el dominio:
1
2
3
4
System.out.print("nombre del PC: ");
System.out.println(ip.getHostName());
System.out.print("dominio del PC: ");
System.out.println(ip.getCanonicalHostName());

1
2
nombre del PC: Dar10-PC
dominio del PC: algunDominio



Ip pública


Para hallar nuestra ip pública debemos recurrir a un servicio como por ejemplo http://checkip.amazonaws.com

Este servicio de amazon, nos devuelve un InputStream con nada más ni nada menos que la ip del solicitando, pero nos vale para obtener nuestra propia ip publica.

 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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
...
URL ipPublica;
BufferedReader in = null;
InputStreamReader isr = null;
try {
    ipPublica = new URL("http://checkip.amazonaws.com");
    isr = new InputStreamReader(ipPublica.openStream());
    in = new BufferedReader(isr);
    String ip = in.readLine(); 
    System.out.print("IP publica: ");
    System.out.println(ip);
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (in != null) {
            in.close();
        }
        if(isr != null){
            isr.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1
IP publica: aqui va tu ip

[Métodos] Reemplazar caracteres con acento, tildes, signos diacriticos, etc

Mi problema, windows no acepta caracteres diacriticos para nombres de archivos o directorios, como los acentos graves y agudos ( ´ ) y ( ` ), el acento circunflejo ( ^ ), la diéresis ( ¨ ), la virgulilla ( ~ ), la cedilla ( ¸ ), la colita ( ˛ ), la coma ( , ), el doble acento agudo, ( ˝ ), el doble acento grave, ( `` ) , el carón ( ˇ ), el breve ( ˘ ), el macrón ( ˉ ), el anillo ( ˚ ), el punto ( • ) el garfio ( ̉ )
ja lo saque de wikipedia!

Entonces pense en removeer los caracteres que ningún sistema operativo permite.
1
String invalidCharRemoved = fileName.replaceAll("[\\\\/:*?\"<>|]", "");

Este patrón remueve aquellos caracteres que windows nos informa con una vigneta:

Pero aun asi, los acentos, la Ñ que si son admitos en la mayorias de distribuciones de windows siguen estando, pero justo el servidor productivo no era uno de ellos.
La siguiente solucion, aunque torpe, satisfacia la problematica y permitía a la aplicación seguir funcionando:
1
string.replace("á", "").replace("é", "").replace("í", "").replace("ó", "").replace("ú", "").replace("ñ", "")

Aunque funcional, a gusto personal no es aceptable:
1
evaluación desempeño región aledaños --> evaluacin desempeo regin aledaos

Para lo cual encontré 2 posibles soluciones: Java.text.Normalizer y org.apache.commons.lang3.StringUtils

Normalizer

1
2
3
4
5
6
import java.text.Normalizer;
...
private static String normalizeUsingJavaText(String source){
    source = Normalizer.normalize(source, Normalizer.Form.NFD);
    return source.replaceAll("[^\\p{ASCII}]", "");
}

Esto podria ser usado asi:
1
2
3
4
5
public static void main(String[] args){
    String string = "áéíóúñ";
    System.out.println(normalizeUsingJavaText(cadenaLoca()));
    //salida --> aeioun
}


StringUtils


Esta es un dependencia, y por lo cual hay que importarla por ejemplo con maven:
1
2
3
4
5
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.0</version>
</dependency>

Simplemente basta con llamar al metodo stripAccents:
1
2
3
4
5
6
import org.apache.commons.lang3.StringUtils;
...
private static String normalizeUsingApacheStringUtils(String source){
    String input = StringUtils.stripAccents(source);
    return input;
}

Esto lo implemente asi: (Esta fué la solución ganadora)
1
2
3
4
5
public static void main(String[] args){
    String string = "áéíóúñ";       
    System.out.println(normalizeUsingApacheStringUtils(string));
    // salida -> aeioun
}

Java 25 de 2025