Category Archives: Uncategorized

Simple (DOM) DocumentBuilder para Java

Hola Amigos,

Acá comparto una clase que ayuda a crear una instancia de un java DOM Document.

Estas son las características de la clase:

  1. Te quita todo el tedioso trabajo de hacer explícitamente el catch de las excepciones, haciendo que tu código sea mas legible y entendible.
  2. Las excepciones son manejadas con un solo handler, haciendo que puedas mejorar la clase aumentar varios builders y manejar las excepciones en un solo método.
  3. También pueden apreciar que la instancia del DocumentBuilderFactory es inicializado estáticamente.

Luego mas abajo podrán ver las pruebas de unidad con solo casos mas simple y el manejo de una excepción.

Si desean bajar el código, este esta disponible en: https://github.com/rhuanca/XMLUtilities

package renidev.utils.xml;
 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
 
/**
 * This class helps to create a instance of a DOM document instance
 * simplifying the way to create it.
 * @author Renan Huanca
 */
public class SimpleDocumentBuilder {
    private static DocumentBuilder documentBuilder;
 
    static {
        try {
            documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new RuntimeException("Unable to get document builder. - "+ e.getMessage(), e);
        }
    }
 
    /**
     * Allow to create a DOM Document instance with the given parameter.
     * 
     * @param xml
     * @return
     */
    public static Document buildDocument(String xml) {
        Document doc = null;
        try {
            doc = documentBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
        } catch (Exception e) {
            handleException(e);
        } 
        return doc;
    }
 
    /**
     * Allow to create a DOM Document instance with the given parameter.
     * @param stream
     * @return
     */
    public static Document buildDocument(InputStream stream) {
        Document doc = null;
        try {
            doc = documentBuilder.parse(stream);
        } catch (Exception e) {
            handleException(e);
        } 
        return doc;
    }
 
    public static void handleException(Exception e){
        if(e instanceof IOException) {
            throw new RuntimeException("Unable to read xml - " + e.getMessage(), e);
        } else if (e instanceof SAXParseException) {
            SAXParseException exception = (SAXParseException) e;
            throw new RuntimeException("Unable to parse xml - Line: " + 
                    exception.getLineNumber() + " - " + e.getMessage(), e);
        } else if ( e instanceof SAXException) {
            throw new RuntimeException("Unable to parse xml - " + e.getMessage(), e);
        } else {
            throw new RuntimeException(e);
        }
    }
}
package renidev.utils.xml;
 
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import static org.junit.Assert.*;
 
public class SimpleDocumentBuilderTest {
 
    @Test
    public void one_node(){
        String xml = "<data>hello world</data>";
        Document doc = SimpleDocumentBuilder.buildDocument(xml);
        Node dataNode = doc.getFirstChild();
        assertEquals(1, dataNode.getChildNodes().getLength());
        assertEquals("hello world", dataNode.getTextContent());
    }
 
    @Test
    public void one_level(){
        String xml = "<data><child>hello world</child></data>";
        Document doc = SimpleDocumentBuilder.buildDocument(xml);
        Node dataNode = doc.getFirstChild();
        assertEquals(1, dataNode.getChildNodes().getLength());
        assertEquals("hello world", dataNode.getFirstChild().getTextContent());
    }
 
    @Test 
    public void test_exception(){
        String xml = "<data>hello world<data>";
        try {
            @SuppressWarnings("unused")
            Document doc = SimpleDocumentBuilder.buildDocument(xml);
        } catch (RuntimeException e) {
            assertEquals("Unable to parse xml - Line: 1 - XML document structures must start and end within the same entity.", e.getMessage());
            return;
        }
        fail("No exception was throw");
    }
}

Aplicación multi-modulo “Hola Mundo” con Maven

Acá muestro un ejemplo de una aplicación multi-modulo usando maven.

El ejemplo esta basado en este articulo: Chapter 7. Multi-module Enterprise Project

Descripción

Básicamente este ejemplo es solo una aplicación que muestra un el texto “Hola Mundo”.

Esta aplicación esta compuesta por dos módulos: ‘my-webapp’, que define una sevlet que imprime un mensaje y ‘my-module’ que contiene un servicio que devuelve el mensaje que imprime la servlet.

Esta es la estructura de directorios y archivos:

multiapp/
¦   pom.xml
+---my-module
¦   ¦   pom.xml
¦   +---src
¦       +---main
¦           +---java
¦                   HelloWorldService.java
+---my-webapp
    ¦   my-webapp.iml
    ¦   pom.xml
    +---src
        +---main
            +---java
            ¦       HelloWorldServlet.java
            +---webapp
                ¦   index.jsp
                +---WEB-INF
                        web.xml

Archivos pom.xml

pom.xml principal
<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>edu.renan</groupId>
    <artifactId>multiapp</artifactId>
    <packaging>pom</packaging>
    <version>1.0</version>
    <name>Test Modules App</name>
    <modules>
        <module>my-module</module>
        <module>my-webapp</module>
    </modules>
    <dependencies>
        <dependency>
            <groupId>net.sourceforge.openutils</groupId>
            <artifactId>openutils-testing-testng</artifactId>
            <version>2.2.2</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>multiapp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

La parte importante en el pom.xml principal es que se definen los módulos: my-webapp y my-module dentro de la etiqueta <modules>

También hay que tomar en cuenta que el packaging es definido como ‘pom’

pom.xml – my-module
<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>
	<parent>
		<groupId>edu.renan</groupId>
		<artifactId>testmodules</artifactId>
		<version>1.0</version>
	</parent>
	<artifactId>my-module</artifactId>
	<packaging>jar</packaging>
	<name>my-module</name>
</project>

Acá estamos definiendo cual sera el modulo padre usando la etiqueta ≷parent> y el packaging como ‘jar’. Utilice jar por que este modulo generara un jar file.

pom.xml – my-webapp
<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>
    <parent>
        <groupId>edu.renan</groupId>
        <artifactId>testmodules</artifactId>
        <version>1.0</version>
    </parent>
    <artifactId>my-webapp</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>my-webapp</name>
    <dependencies>
        <dependency>
            <groupId>servletapi</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>edu.renan</groupId>
            <artifactId>my-module</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>mywebapp</finalName>
    </build>
</project>

Acá definimos un parent lo mismo que el anterior, pero para el packaging usamos ‘war’, por que este modulo generara una aplicación web.

Classes java y web.xml

HelloWorldService
public class HelloWorldService {
    public String sayHello(){
        return "Hola Mundo";
    }
}

Como verán es solo una clase con un método con un método que retorna el mensaje “Hola Mundo”.

HelloWorldServlet
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
 
public class HelloWorldServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HelloWorldService helloWorldService = new HelloWorldService();
        response.getWriter().println(helloWorldService.sayHello());
    }
}

Esta servlet solo llama al servicio definido anteriormente.

web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
     version="2.4">
 
    <display-name>My Web App</display-name>
    <servlet>
        <servlet-name>helloWorldServlet</servlet-name>
        <servlet-class>HelloWorldServlet</servlet-class>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>helloWorldServlet</servlet-name>
        <url-pattern>/helloWorld</url-pattern>
    </servlet-mapping>
 
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Espero este ejemplo les sirva mucho, si quieren mas recursos acá tienen algunos que encontré:

El código fuente lo pueden encontrar en https://github.com/rhuanca/examples/tree/master/maven-multimodule.