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.
¿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.
2. Crear un Web Aplication
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 MySqlDAOFactory y SqlServerDAOFactory 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( } 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( "jdbc:mysql://localhost:3306/ReealoDB2019?useTimezone=true&serverTimezone=UTC&autoReconnect=true&useSSL=false" , "root" , "root" ); } 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.
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!