01 mayo, 2020

Crear un CRUD Web Service Rest-Json en Netbeans usando JEE specification

En este post aprenderemos a crear un servicio web Java Rest-Json usando JEE 6 specification. Crearemos los métodos para un CRUD que obtengan la información de una base de datos SQL Server a la cual nos conectaremos mediante JDBC.  Asimismo, implementaremos el patrón arquitectónico MVC, el patrón de diseño DAO y utilizaremos la IDE de Netbeans.



¿Qué es MVC?

Modelo-vista-controlador es un patrón de arquitectura de software, que separa los datos y la lógica de negocio de una aplicación de su representación y el módulo encargado de gestionar los eventos y las comunicaciones.

¿Qué es DAO?

un objeto de acceso a datos (en inglés, data access object, abreviado DAO) es un componente de software que suministra una interfaz común entre la aplicación y uno o más dispositivos de almacenamiento de datos, tales como una Base de datos o un archivo. El término se aplica frecuentemente al Patrón de diseño Object.

Los Objetos de Acceso a Datos pueden usarse en Java para aislar a una aplicación de la tecnología de persistencia Java subyacente (API de Persistencia Java), la cual podría ser JDBC, JDO, Enterprise JavaBeans, TopLink, EclipseLink, Hibernate, iBATIS, o cualquier otra tecnología de persistencia. Usar Objetos de Acceso de Datos significa que la tecnología subyacente puede ser actualizada o cambiada sin cambiar otras partes de la aplicación.

¿Qué es JDBC?

Java Database Connectivity (en español: Conectividad a bases de datos de Java), más conocida por sus siglas JDBC, es una API que permite la ejecución de operaciones sobre bases de datos desde el lenguaje de programación Java, independientemente del sistema operativo donde se ejecute o de la base de datos a la cual se accede, utilizando el dialecto SQL del modelo de base de datos que se utilice.


PASOS - CREAR EL WEB SERVICE

1. Crear la base de datos

Creamos la siguiente base de datos en el motor MS SQL Server y MySQL Server.
1
2
3
4
5
6
7
8
9
10
create database ReealoDB2019;
use ReealoDB2019;
create table productos (
 codProd char(4) primary key,
 descripcion varchar(30) not null,
 detalle varchar(300) not null,
 stock int not null,
 precio numeric (8,2) not null,
 imagen varchar (30) not null
);

2. Crear un Web Aplication

Abrimos el Netbeans y nos dirigimos a la parte superior para hacer clic en la opción File/New Project/. En la ventana que aparece debemos seleccionar la categoria Java Web y el elegir el proyecto Web Application.





3. Crear el DTO/VO

Creamos la clase ProductoDTO dentro del paquete com.aprendec.dao.beans.
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package com.aprendec.dao.beans;
 
public class ProductoDTO {
 
    private String codigo;
    private String descripcion;
    private String detalle;
    private int stock;
    private double precio;
    private String imagen;
 
    public ProductoDTO(String codigo, String descripcion, String detalle, int stock, double precio, String imagen) {
        this.codigo = codigo;
        this.descripcion = descripcion;
        this.detalle = detalle;
        this.stock = stock;
        this.precio = precio;
        this.imagen = imagen;
    }
 
    public ProductoDTO(String codigo) {
        this.codigo = codigo;
 
    }
 
    /**
     * @return the codigo
     */
    public String getCodigo() {
        return codigo;
    }
 
    /**
     * @param codigo the codigo to set
     */
    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }
 
    /**
     * @return the descripcion
     */
    public String getDescripcion() {
        return descripcion;
    }
 
    /**
     * @param descripcion the descripcion to set
     */
    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }
 
    /**
     * @return the detalle
     */
    public String getDetalle() {
        return detalle;
    }
 
    /**
     * @param detalle the detalle to set
     */
    public void setDetalle(String detalle) {
        this.detalle = detalle;
    }
 
    /**
     * @return the stock
     */
    public int getStock() {
        return stock;
    }
 
    /**
     * @param stock the stock to set
     */
    public void setStock(int stock) {
        this.stock = stock;
    }
 
    /**
     * @return the precio
     */
    public double getPrecio() {
        return precio;
    }
 
    /**
     * @param precio the precio to set
     */
    public void setPrecio(double precio) {
        this.precio = precio;
    }
 
    /**
     * @return the imagen
     */
    public String getImagen() {
        return imagen;
    }
 
    /**
     * @param imagen the imagen to set
     */
    public void setImagen(String imagen) {
        this.imagen = imagen;
    }
 
    @Override
    public String toString() {
        return "Producto{" + "codigo=" + codigo + ", descripcion=" + descripcion + ", detalle=" + detalle + ", stock=" + stock + ", precio=" + precio + ", imagen=" + imagen + '}';
    }
 
}

4. Crear el DAO

Creamos la interface ProductoDAO dentro del paquete com.aprendec.dao.
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
/**
 *
 * Una interfaz es una clase completamente abstracta, es decir es una clase sin
 * implementación. No es necesario ponerle abstract ya que lo son
 * implicitamente. Si adicionalmente tiene miembros-datos, estos seran
 * constantes static y final.
 */
package com.aprendec.dao;
 
import com.aprendec.dao.beans.ProductoDTO;
import java.util.List;
 
public interface ProductoDAO {
 
    public String obtenerCodProd();
 
    public ProductoDTO obtenerProducto(String codigo);
 
    public List<productodto> listarProductos(String nombre);
 
    public int registrarProducto(ProductoDTO productoDTO);
 
    public int actualizarProducto(ProductoDTO productoDTO);
 
    public int eliminarProducto(String codigo);
 
}

5. Crear la fabrica de DAOs

Crear la clase abstracta DAOFactory dentro del paquete com.aprendec.dao.factory.
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
package com.aprendec.dao.factory;
 
import com.aprendec.dao.ProductoDAO;
 
/**
 *
 * Fabrica especifica de DAOs
 */
public abstract class DAOFactory {
 
    // Definimos unas constantes por cada base de datos
    public static final int MYSQL = 1;
    public static final int SQLSERVER = 2;
 
    // Existirá un método get por cada DAO que exista en el sistema
    public abstract ProductoDAO getProductoDAO();
 
    public static DAOFactory getDAOFactory(int whichFactory) {
        switch (whichFactory) {
            case MYSQL:
                return new MySqlDAOFactory();
            case SQLSERVER:
                return new SqlServerDAOFactory();
            default:
                return null;
        }
    }
}

El método getDAOFactory() recibirá como parámetro el origen de datos y según eso invocará el DAO especifico a dicho motor de base de datos.

Creamos las clases MySqlDAOFactorySqlServerDAOFactory que extiendan de DAOFactory dentro del paquete com.aprendec.dao.factory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.aprendec.dao.factory;
 
import com.aprendec.dao.ProductoDAO;
import com.aprendec.dao.SqlServerProductoDAO;
 
public class SqlServerDAOFactory extends DAOFactory {
 
    public SqlServerDAOFactory() {
    }
 
    // Estamos aplicando la 2da forma de polimorfismo.
    // Una clase puede ser enmascarada con la interface que implementa
    @Override
    public ProductoDAO getProductoDAO() {
        return new SqlServerProductoDAO();
    }
 
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.aprendec.dao.factory;
 
import com.aprendec.dao.ProductoDAO;
import com.aprendec.dao.MySqlProductoDAO;
 
public class MySqlDAOFactory extends DAOFactory {
 
    public MySqlDAOFactory() {
    }
 
    // Estamos aplicando la 2da forma de polimorfismo.
    // Una clase puede ser enmascarada con la interface que implementa
    @Override
    public ProductoDAO getProductoDAO() {
        return new MySqlProductoDAO();
    }
 
}


En nuestro ejemplo vamos a implementar los métodos de los DAOs SqlServerDAOFactory y MySqlDAOFactory, ya que estamos trabajando con estos 2 motores de bases de datos.  Esto es la ventaja de usar DAO en nuestros proyectos, ya que si en un momento dado nuestra aplicación cambiase de base de datos, solo tendríamos que implementar los métodos para ese nuevo DAO. Para el caso que mudemos de SQL Server a MySQL hemos creado el DAO MySqlDAOFactory, en este DAO tendríamos que implementar los mismos método que hicimos para SQL Server pero para el motor de base de datos MySQL, de la misma manera si tuviéramos que usar Oracle, PostgreSQL u cualquier otro motor de base de datos, tendríamos que crear esos nuevos DAOs.
Creamos la clase SQLServerConexion dentro del paquete com.aprendec.util.

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
/*
 * Clase conexión a base de datos SQL Server
 */
package com.aprendec.util;
 
import java.sql.Connection;
import java.sql.DriverManager;
 
public class SqlServerConexion {
 
    static {
        try {
            // CARGAR EL CONTROLADOR DE BD
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        } catch (Exception e) {
            System.out.println("[SqlServerConexion] Error al cargar el driver de conexión");
            e.printStackTrace();
        }
    }
 
    public static Connection obtenerConexion() {
        Connection con = null;
        try {
            con = DriverManager.getConnection(
                    "jdbc:sqlserver://XXKOKOXXT-PC:1433;databasename=ReealoDB2019", "sa", "sql");
        } catch (Exception e) {
            System.out.println("[SqlServerConexion] Error al obtener la conexión");
            e.printStackTrace();
        }
        return con;
    }
     
}

Creamos la clase MySQLConexion dentro del paquete com.aprendec.util.

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
/*
 * Clase conexión a base de datos MySQL
 */
package com.aprendec.util;
 
import java.sql.Connection;
import java.sql.DriverManager;
 
public class MySqlConexion {
        
    static {
        try {
            // CARGAR EL CONTROLADOR DE BD
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (Exception e) {
            System.out.println("[MySqlConexion] Error al cargar el driver de conexión");
            e.printStackTrace();
        }
    }
 
    // Glassfish 4.2.1 y MYSQL 8.0 (que ahora tiene caching_sha2_password) no son compatible entre sí. Actualice su versión de Glassfish o use Apache
    public static Connection obtenerConexion() {
        Connection con = null;
        try {
            con = DriverManager.getConnection(
        } catch (Exception e) {
            System.out.println("[MySqlConexion] Error al obtener la conexión: ");
            e.printStackTrace();
        }
        return con;
    }
     
}

Creamos la clase Constantes dentro del paquete com.aprendec.util.

1
2
3
4
5
6
7
package com.aprendec.util;
 
public class Constantes {
 
    public static final int ORIGENDATOS = 2; // 1: MySQL, 2: SQL Server
 
}

Ahora, debemos de agregar los jars de conexión SQL Server y MySQL.

Para ello, debemos hacer clic derecho al el proyecto y seleccionar la opción properties. En la venta que aparece debemos seleccionar la opción Libraries y agregar el jar de conexión SQL Server y el jar de conexión MySQL.


Creamos las clases que van a implementar los DAOs.

Crearemos la clase SQLServerProductoDAO y MySqlProductoDAO. Normalmente por cada entidad de nuestro modelo de datos tendremos un DAO.

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
 *
 * Por cada entidad de nuestro modelo de datos, normalmente tendremos un DAO. Un
 * DAO define todas las operaciones que necesitemos realizar sobre una entidad
 * Un DAO expone sus métodos al mundo a través de su interface. La clase nos dice
 * "cómo" vamos a hacerlo
 */
package com.aprendec.dao;
 
import com.aprendec.dao.beans.ProductoDTO;
import com.aprendec.util.SqlServerConexion;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
public class SqlServerProductoDAO implements ProductoDAO {
 
    @Override
    public String obtenerCodProd() {
        String cod = "image";
        try {
            Connection cn = SqlServerConexion.obtenerConexion();
            String query = "SELECT 'P' + RIGHT('000' + CONVERT(varchar(3), MAX(CONVERT(int, RIGHT(codProd, 3))) + 1), 3) FROM productos";
            PreparedStatement ps = cn.prepareCall(query);
            ResultSet rs = ps.executeQuery();
            if (rs.next()){
                cod = rs.getString(1);
            }
        } catch (SQLException e) {
            System.out.println("[SqlServerProductoDAO] Error al intentar obtener el código del producto: " + e);
        }
        return cod;
    }
 
    @Override
    public ProductoDTO obtenerProducto(String codigo) {
        ProductoDTO objCli = null;
        Connection cn = SqlServerConexion.obtenerConexion();
        try {
            String sentencia = "SELECT * FROM productos WHERE codProd = ?";
            PreparedStatement pst = cn.prepareStatement(sentencia);
            pst.setString(1, codigo);
            ResultSet rs = pst.executeQuery();
            if (rs.next()) {
                objCli = new ProductoDTO(rs.getString(1),
                        rs.getString(2),
                        rs.getString(3),
                        rs.getInt(4),
                        rs.getDouble(5),
                        rs.getString(6));
            }
            cn.close();
        } catch (SQLException e) {
            System.out.println("[SqlServerProductoDAO] Error al intentar obtener la información: " + e);
        }
        return objCli;
    }
 
    @Override
    public List<productodto> listarProductos(String nombre) {
        List<productodto> productosList = new ArrayList<productodto>();
        Connection cn = SqlServerConexion.obtenerConexion();
        try {
            String query = "SELECT * FROM productos WHERE descripcion like ?";
            PreparedStatement ps = cn.prepareCall(query);
            ps.setString(1, "%" + nombre + "%");
            ResultSet rs = ps.executeQuery();
            ProductoDTO p;
            while (rs.next()) {
                p = new ProductoDTO(rs.getString(1),
                                    rs.getString(2),
                                    rs.getString(3),
                                    rs.getInt(4),
                                    rs.getDouble(5),
                                    rs.getString(6));
                productosList.add(p);
            }
        } catch (SQLException e) {
            System.out.println("SQLException: " + e.getMessage());
        }
        return productosList;
    }
 
    @Override
    public int registrarProducto(ProductoDTO productoDTO) {
        int resultado = 0;
        String sql = "INSERT INTO productos (codProd, descripcion, detalle, stock, precio, imagen) "
                + "VALUES ( (SELECT 'P' + RIGHT('000' + CONVERT(varchar(3), MAX(CONVERT(int, RIGHT(codProd, 3))) + 1), 3) FROM productos), ?, ?, ?, ?, ? )";
        Connection cn = SqlServerConexion.obtenerConexion();
        try {
            PreparedStatement ps = cn.prepareStatement(sql);
            ps.setString(1, productoDTO.getDescripcion());
            ps.setString(2, productoDTO.getDetalle());
            ps.setInt(3, productoDTO.getStock());
            ps.setDouble(4, productoDTO.getPrecio());
            ps.setString(5, productoDTO.getImagen());
            resultado = ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            System.out.println("[SqlServerProductoDAO] Error al intentar almacenar la información: " + e);
        } finally {
            try {
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                System.out.println("[SqlServerProductoDAO] Error al intentar cerrar la conexión: " + ex.getMessage());
            }
        }
        return resultado;
    }
 
    @Override
    public int actualizarProducto(ProductoDTO productoDTO) {
        int resultado = 0;
        String sql = "UPDATE productos set descripcion = ?, detalle = ?, stock = ?, precio = ?, imagen = ? where codProd = ?";
        Connection cn = SqlServerConexion.obtenerConexion();
        try {
            PreparedStatement ps = cn.prepareStatement(sql);
            ps.setString(1, productoDTO.getDescripcion());
            ps.setString(2, productoDTO.getDetalle());
            ps.setInt(3, productoDTO.getStock());
            ps.setDouble(4, productoDTO.getPrecio());
            ps.setString(5, productoDTO.getImagen());
            ps.setString(6, productoDTO.getCodigo());
            resultado = ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            System.out.println("[SqlServerProductoDAO] Error al intentar actualizar la información: " + e);
        } finally {
            try {
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                System.out.println("[SqlServerProductoDAO] Error al intentar cerrar la conexión: " + ex.getMessage());
            }
        }
        return resultado;
    }
 
    @Override
    public int eliminarProducto(String codigo) {
        int resultado = 0;
        String sql = "DELETE productos where codProd  = '" + codigo + "'";
        Connection cn = SqlServerConexion.obtenerConexion();
        try {
            PreparedStatement ps = cn.prepareStatement(sql);
            resultado = ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            System.out.println("[SqlServerProductoDAO] Error al intentar eliminar la información: " + e);
        } finally {
            try {
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                System.out.println("[SqlServerProductoDAO] Error al intentar cerrar la conexión: " + ex.getMessage());
            }
        }
        return resultado;
    }
 
}

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/**
 *
 * Por cada entidad de nuestro modelo de datos, normalmente tendremos un DAO. Un
 * DAO define todas las operaciones que necesitemos realizar sobre una entidad
 * Un DAO expone sus métodos al mundo a través de su interface. La clase nos dice
 * "cómo" vamos a hacerlo
 */
package com.aprendec.dao;
 
import com.aprendec.dao.beans.ProductoDTO;
import com.aprendec.util.MySqlConexion;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
/**
 *
 * @author XxkokoxXT
 */
public class MySqlProductoDAO implements ProductoDAO {
 
    public MySqlProductoDAO() {
    }
 
    @Override
    public String obtenerCodProd() {
        String cod = "image";
        try {
            Connection cn = MySqlConexion.obtenerConexion();
            String query = "SELECT CONCAT('P', LPAD(MAX(RIGHT(codProd, 1)+1), 3, '0')) FROM productos;";
            PreparedStatement ps = cn.prepareCall(query);
            ResultSet rs = ps.executeQuery();
            if (rs.next()){
                cod = rs.getString(1);
            }
        } catch (SQLException e) {
            System.out.println("[MySqlProductoDAO] Error al intentar obtener el código del producto: " + e);
        }
        return cod;
    }
 
    @Override
    public ProductoDTO obtenerProducto(String codigo) {
        ProductoDTO objCli = null;
        Connection cn = MySqlConexion.obtenerConexion();
        try {
            String sentencia = "SELECT * FROM productos WHERE codProd = ?";
            PreparedStatement pst = cn.prepareStatement(sentencia);
            pst.setString(1, codigo);
            ResultSet rs = pst.executeQuery();
            if (rs.next()) {
                objCli = new ProductoDTO(rs.getString(1),
                        rs.getString(2),
                        rs.getString(3),
                        rs.getInt(4),
                        rs.getDouble(5),
                        rs.getString(6));
            }
            cn.close();
        } catch (SQLException e) {
            System.out.println("[MySqlProductoDAO] Error al intentar obtener la información: " + e);
        }
        return objCli;
    }
 
    @Override
    public List<productodto> listarProductos(String nombre) {
        List<productodto> productosList = new ArrayList<productodto>();
        Connection cn = MySqlConexion.obtenerConexion();
        try {
            String query = "SELECT * FROM productos WHERE descripcion LIKE ?";
            PreparedStatement ps = cn.prepareCall(query);
            ps.setString(1, "%" + nombre + "%");
            ResultSet rs = ps.executeQuery();
            ProductoDTO p;
            while (rs.next()) {
                p = new ProductoDTO(rs.getString(1),
                                    rs.getString(2),
                                    rs.getString(3),
                                    rs.getInt(4),
                                    rs.getDouble(5),
                                    rs.getString(6));
                productosList.add(p);
            }
        } catch (SQLException e) {
            System.out.println("[MySqlProductoDAO] Error al intentrar listar la información: " + e);
        }
        return productosList;
    }
 
    @Override
    public int registrarProducto(ProductoDTO productoDTO) {
        int resultado = 0;
        String sql = "INSERT INTO productos (codProd, descripcion, detalle, stock, precio, imagen) "
                //+ "VALUES (select CONCAT('P', LPAD(MAX(RIGHT(codProd, 1)+1), 3, '0')) from productos, ?, ?, ?, ?, ? )";
        + "SELECT CONCAT('P', LPAD(MAX(RIGHT(codProd, 1)+1), 3, '0')), ?, ?, ?, ?, ? FROM productos";
        Connection cn = MySqlConexion.obtenerConexion();
        try {
            PreparedStatement ps = cn.prepareStatement(sql);
            ps.setString(1, productoDTO.getDescripcion());
            ps.setString(2, productoDTO.getDetalle());
            ps.setInt(3, productoDTO.getStock());
            ps.setDouble(4, productoDTO.getPrecio());
            ps.setString(5, productoDTO.getImagen());
            resultado = ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            System.out.println("[MySqlProductoDAO] Error al intentar almacenar la información: " + e);
        } finally {
            try {
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                System.out.println("[MySqlProductoDAO] Error al intentar cerrar la conexión: " + ex.getMessage());
            }
        }
        return resultado;
    }
 
    @Override
    public int actualizarProducto(ProductoDTO productoDTO) {
        int resultado = 0;
        String sql = "UPDATE productos SET descripcion = ?, detalle = ?, stock = ?, precio = ?, imagen = ? where codProd = ?";
        Connection cn = MySqlConexion.obtenerConexion();
        try {
            PreparedStatement ps = cn.prepareStatement(sql);
            ps.setString(1, productoDTO.getDescripcion());
            ps.setString(2, productoDTO.getDetalle());
            ps.setInt(3, productoDTO.getStock());
            ps.setDouble(4, productoDTO.getPrecio());
            ps.setString(5, productoDTO.getImagen());
            ps.setString(6, productoDTO.getCodigo());
            resultado = ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            System.out.println("[MySqlProductoDAO] Error al intentar actualizar la información: " + e);
        } finally {
            try {
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                System.out.println("[MySqlProductoDAO] Error al intentar cerrar la conexión: " + ex.getMessage());
            }
        }
        return resultado;
    }
 
    @Override
    public int eliminarProducto(String codigo) {
        int resultado = 0;
        String sql = "DELETE FROM productos WHERE codProd  = '" + codigo + "'";
        Connection cn = MySqlConexion.obtenerConexion();
        try {
            PreparedStatement ps = cn.prepareStatement(sql);
            resultado = ps.executeUpdate();
            ps.close();
        } catch (SQLException e) {
            System.out.println("[MySqlProductoDAO] Error al intentar eliminar la información: " + e);
        } finally {
            try {
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                System.out.println("[MySqlProductoDAO] Error al intentar cerrar la conexión: " + ex.getMessage());
            }
        }
        return resultado;
    }
     
}

  • Hasta aquí hemos terminado de desarrollar nuestro modelo, que a su vez esta aplicando el patrón DAO (Objeto de Acceso a Datos) que permite que nuestra aplicación no se esté ligada a una sola fuente de datos, sino que para el momento que sea necesario, nosotros podamos cambiar de motor de base de datos. Los datos serán traído independientemente si están en una base de datos o en un archivo.

4. Crear el Servicio (DTO/BO)

Crear la clase ProductoService dentro del paquete com.aprendec.service.
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
38
39
40
41
42
package com.aprendec.service;
 
import com.aprendec.dao.factory.DAOFactory;
import com.aprendec.dao.ProductoDAO;
import com.aprendec.dao.beans.ProductoDTO;
import com.aprendec.util.Constantes;
import java.util.List;
 
public class ProductoService {
 
    // Referenciamos la fábrica específica de daos y le indicamos nuestro origen de datos (MSSQL)
    DAOFactory fabrica = DAOFactory.getDAOFactory(Constantes.ORIGENDATOS);
 
    // Le pedimos a la fábrica específica el o los daos que necesitemos
    ProductoDAO objProductoDAO = fabrica.getProductoDAO();
 
    // Operaciones
    public String obtenerCodProd() {
        return objProductoDAO.obtenerCodProd();
    }
 
    public ProductoDTO obtenerProducto(String codigo) {
        return objProductoDAO.obtenerProducto(codigo);
    }
 
    public List<productodto> listarProductos(String nombre) {
        return objProductoDAO.listarProductos(nombre);
    }
 
    public int registrarProducto(ProductoDTO productoDTO) {
        return objProductoDAO.registrarProducto(productoDTO);
    }
 
    public int actualizarProducto(ProductoDTO productoDTO) {
        return objProductoDAO.actualizarProducto(productoDTO);
    }
 
    public int eliminarProducto(String codigo) {
        return objProductoDAO.eliminarProducto(codigo);
    }
     
}

REST

5. Crear el Servicio web Restful

Crear la clase Utilidades dentro del paquete com.aprendec.util.
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.aprendec.util;
 
import com.aprendec.service.ProductoService;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.bind.DatatypeConverter;
 
public class Utilidades {
     
    private final String ruta = "E:\\";
    //private final String ruta = "/opt/glassfish/glassfish/domains/domain1/applications/ROOT-160/imagenes/";
    //private final String ruta = "web\\imagenes\\";
 
    /* Este método se encarga de decodificar una imagen en formato base 64 y de
     * guardarla en una ruta del disco duro */
    public String decodificarImagen(String imgbase64, String codProd){
        //String base64String = "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAHkAAAB5C...";
        String base64String = "data:image/jpg;base64," + imgbase64;
        String[] strings = base64String.split(",");
        String extension;
        switch (strings[0]) {//comprobar la extensión de la imagen
            case "data:image/jpeg;base64":
                extension = "jpeg";
                break;
            case "data:image/png;base64":
                extension = "png";
                break;
            default://debería escribir más casos para más tipos de imágenes
                extension = "jpg";
                break;
        }
         
        // convertimos la cadena base64 a datos binarios
        byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
        
        // obtenemos el codigo para el nuevo producto
        if (codProd == null || codProd.equals("")){
            codProd = new ProductoService().obtenerCodProd();
        }
         
        // generamos un nombre para la imagen
        String imagen = "image" + codProd + "." + extension;
        File file = new File(ruta + imagen);
        //System.out.println("[Utilidades] Ruta en donde se guardará la imagen: " + file.getAbsolutePath());
        
        // eliminamos el archivo para volverla a crear
        if (file.exists()){
            if (file.delete())
                System.out.println("[Utilidades] La imagen ha sido borrada satisfactoriamente");
            else
                System.out.println("[Utilidades] La imagen no puede ser borrada");
        }
         
        // siempre creará el archivo a pesar de que no se haya registrado el producto en la base de datos
        try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file))) {
            outputStream.write(data);
            System.out.println("[Utilidades] La imagen se ha guardado satisfactoriamente");
        } catch (IOException e) {
            System.out.println("[Utilidades] Error al intentar guardar la imagen: ");
            e.printStackTrace();
        }
 
        return imagen;
    }
 
    public void eliminarImagen(String codigo){
        String imagen = ruta + ("image" + codigo + ".jpg");
        File fichero = new File(imagen);
        if (fichero.delete()) {
            System.out.println("[Utilidades] El fichero ha sido borrado satisfactoriamente");
        } else {
            System.out.println("[Utilidades] El fichero no puede ser borrado");
        }
    }
 
}

Crear la clase ReealoServiceRest dentro del paquete com.aprendec.ws.rest.
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package com.aprendec.ws.rest;
 
import com.aprendec.dao.beans.ProductoDTO;
import com.aprendec.service.ProductoService;
import com.aprendec.util.Utilidades;
import com.google.gson.Gson;
import java.io.File;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
 
@Path("aprendec")
public class ReealoServiceRest {
     
    public ReealoServiceRest() {
    }
 
    /* TABLA PRODUCTO */
    @GET
    @Path("obtenerProducto")
    @Produces(MediaType.APPLICATION_JSON)
    public Response obtenerProducto(@QueryParam("codigo") String codigo) {
        try {
            ProductoDTO producto = new ProductoService().obtenerProducto(codigo);
            String json = new Gson().toJson(producto);
            return Response.ok(json, MediaType.APPLICATION_JSON).build();
        } catch (Exception e) {
            return Response.status(Response.Status.SEE_OTHER).entity("Error: " + e.toString()).build();
        }
    }
 
    @GET
    @Path("listarProductos")
    @Produces(MediaType.APPLICATION_JSON)
    public Response listarProductos(@QueryParam("descripcion") String nombre) {
        try {
            List<productodto> productos = new ProductoService().listarProductos(nombre);
            String json = new Gson().toJson(productos);
            return Response.ok(json, MediaType.APPLICATION_JSON).build();
        } catch (Exception e) {
            return Response.status(Response.Status.SEE_OTHER).entity("Error: " + e.toString()).build();
        }
    }
     
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("registrarProducto")
    public int registrarProducto(String json){
        try {
            Gson gson = new Gson();
            ProductoDTO producto = (ProductoDTO) gson.fromJson(json, ProductoDTO.class);
            // antes de mandar el producto para su registro en la bd, decodificamos y guardamos la imagen que viene en base64
            Utilidades util = new Utilidades();
            String nombreImagen = util.decodificarImagen(producto.getImagen(), null);
            producto.setImagen(nombreImagen);// end
            return new ProductoService().registrarProducto(producto);
        } catch (Exception e) {
            return -1;
        }
    }
 
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("actualizarProducto")
    public int actualizarProducto(String json) {
        try {
            Gson gson = new Gson();
            ProductoDTO producto = (ProductoDTO) gson.fromJson(json, ProductoDTO.class);
            // antes de mandar el producto para su actualización en la bd, decodificamos y guardamos la imagen que viene en base64
            Utilidades util = new Utilidades();
            String nombreImagen = util.decodificarImagen(producto.getImagen(), producto.getCodigo());
            producto.setImagen(nombreImagen);//end
            return new ProductoService().actualizarProducto(producto);
        } catch (Exception e) {
            return -1;
        }
    }
 
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("eliminarProducto")
    public int eliminarProducto(@QueryParam("codigo")String codigo) {
        try {
            int resultado = new ProductoService().eliminarProducto(codigo);
            if (resultado == 1) {
                // eliminar también la imagen del disco duro
                Utilidades utilidades = new Utilidades();
                utilidades.eliminarImagen(codigo);
            }
            return resultado;
        } catch (Exception e) {
            return -1;
        }
    }
 
}

Debemos agregar el jar Gson.

Para ello, debemos hacer clic derecho en el proyecto y seleccionar la opción properties. En la venta que se abre seleccionamos la opción Libraries y agregamos el jar.


Ahora debemos configurar nuestro servicio Rest, para ello, podemos usar Java EE o Jersey.

Para este ejemplo vamos a utilizar Java EE 6 Especification.


Al dar clic en dicha opción, Netbeans nos creará una clase llamada ApplicationConfig dentro del paquete org.netbeans.rest.application.config.


Podemos cambiarle el nombre al paquete si lo deseamos. En mi caso yo lo voy a cambiar para seguir el estándar de los nombre.

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
package com.aprendec.ws.rest.config;
 
import java.util.Set;
import javax.ws.rs.core.Application;
 
@javax.ws.rs.ApplicationPath("rest")
public class ApplicationConfig extends Application {
 
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }
 
    /**
     * Do not modify addRestResourceClasses() method.
     * It is automatically populated with
     * all resources defined in the project.
     * If required, comment out calling this method in getClasses().
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(com.aprendec.ws.rest.ReealoServiceRest.class);
    }
     
}


8. Ejecutar aplicación

Clic derecho al proyecto y seleccionar la opción Run As/ Run on Server.

imagen

Abrir el Advanced Rest Client y probar los métodos que creamos.

BD SQL SERVER



Método listar productos



Métodos obtener productos



Método registrar producto

Nota: La imagen debe estar en base64 (ver ejemplo)


Método actualizar producto



Método eliminar producto


BD MYSQL


Para cambiar de motor de base de datos, solo debemos cambiarle el valor a la propiedad ORIGENDATOS de clase Constantes.



Descargara archivo

No hay comentarios, ¡cuéntame algo!

Me gustaría saber tu opinión. ¡Saludos!