Ejercicio Hibernate

Con lo que hemos visto del enlace anterior vamos a crear en esa misma aplicación una api REST para dar mantenimiento a los países de la bd de trifulcas. Campos:

country_id
country
last_update

El last_update es de la base de datos, lo podemos obviar en nuestro POJO.

Una vez funcione la API podemos crear un mantenimiento web usando MVC. El controlador será un servlet que pasará los datos a una página JSP. Si en la página JSP usamos JSTL (https://github.com/juanpfuentes/Java/blob/main/src/java/jstl.md) todo irá mejor.
¡Ánimo!

Crear la API

Añadimos la siguiente dependencia:

<dependency>
			<groupId>org.json</groupId>
			<artifactId>json</artifactId>
			<version>20220924</version>
		</dependency>

Mapeamos el servlet, creamos un actorDAO para acceder a los datos e implementamos el get:

@WebServlet("/Api/*")
public class Api extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private ActorDAO actorDAO;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Api() {
		super();
		actorDAO = new ActorDAO();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		try {
			String id = request.getPathInfo();
			System.out.println(id);
			if (id == null) {
				List<Actor> actores = actorDAO.getActors();
				JSONArray actoresJSON = new JSONArray(actores);
				response.getWriter().append(actoresJSON.toString());
			} else {
				int idActor = Integer.parseInt(id.substring(1));
				Actor actor = actorDAO.getActor(idActor);
				JSONObject actorJSON = new JSONObject(actor);
				response.getWriter().append(actorJSON.toString());
			}
		} catch (Exception ex) {
			JSONObject mensaje = new JSONObject();
			mensaje.put("Mensaje", "Error en la petición");
			mensaje.put("Error", ex);
			response.getWriter().append(mensaje.toString());
		}
	}

EL POST:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// Me mandarán los valores del actor en formato JSON
		// Tendré que insertarlo en la BD
		JSONObject mensaje = new JSONObject();
		try {
			String data = request.getReader().lines().collect(Collectors.joining());
			JSONObject actorJSON = new JSONObject(data);

			Actor actor = new Actor(0, actorJSON.getString("first_name"), actorJSON.getString("last_name"), null);

			if (actorDAO.addActor(actor)) {
				mensaje.put("Mensaje", "Actor insertado con éxito");
			} else {
				mensaje.put("Mensaje", "Error en la inserción");
			}
			response.getWriter().append(mensaje.toString());
		} catch (Exception ex) {
			mensaje.put("Mensaje", "Error en la petición");
			mensaje.put("Error", ex);
			response.getWriter().append(mensaje.toString());
		}
	}

DAO Actor

Para tener acceso a datos tenemos que tener un POJO que nos represente la entidad y un DAO para las operaciones comunes.

package com.trifulcas.dao;

import java.sql.Date;

public class Actor {

	private int actor_id;
	private String first_name;
	private String last_name;
	private Date last_update;
	
	public Actor(int actor_id, String first_name, String last_name, Date last_update) {
		this.actor_id = actor_id;
		this.first_name = first_name;
		this.last_name = last_name;
		this.last_update = last_update;
	}
	
	/**
	 * @return the actor_id
	 */
	public int getActor_id() {
		return actor_id;
	}
	/**
	 * @param actor_id the actor_id to set
	 */
	public void setActor_id(int actor_id) {
		this.actor_id = actor_id;
	}
	/**
	 * @return the first_name
	 */
	public String getFirst_name() {
		return first_name;
	}
	/**
	 * @param first_name the first_name to set
	 */
	public void setFirst_name(String first_name) {
		this.first_name = first_name;
	}
	
	/**
	 * @return the last_name
	 */
	public String getLast_name() {
		return last_name;
	}
	/**
	 * @param last_name the last_name to set
	 */
	public void setLast_name(String last_name) {
		this.last_name = last_name;
	}
	/**
	 * @return the last_update
	 */
	public Date getLast_update() {
		return last_update;
	}
	/**
	 * @param last_update the last_update to set
	 */
	public void setLast_update(Date last_update) {
		this.last_update = last_update;
	}
	
	public String toString() {
		return actor_id+" | "+first_name+" | "+last_name+" | "+last_update;
	}
	
}

Para acceder a los datos:

public class ActorDAO {

	private Connection con;
	private int max_records = 1000;

	public ActorDAO() {
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sakila", "root", "");

		} catch (Exception ex) {
			System.out.println(ex);
		}
	}

	public Actor getActor(int id) {
		Actor res = null;
		try {
			String sql = "select * from actor where actor_id=?";
			PreparedStatement stmt = con.prepareStatement(sql);

			stmt.setInt(1, id);

			ResultSet rs = stmt.executeQuery();
			if (rs.next()) {
				res = new Actor(rs.getInt("actor_id"), rs.getString("first_name"), rs.getString("last_name"),
						rs.getDate("last_update"));
			}

		} catch (Exception ex) {
			System.out.println(ex);
		}
		return res;
	}

	public List<Actor> getActors(int limite) {
		List<Actor> res = new ArrayList<Actor>();
		try {
			String sql = "select * from actor limit ?";
			PreparedStatement stmt = con.prepareStatement(sql);
			stmt.setInt(1, limite);
			ResultSet rs = stmt.executeQuery();
			while (rs.next()) {
				Actor temp = new Actor(rs.getInt("actor_id"), rs.getString("first_name"), rs.getString("last_name"),
						rs.getDate("last_update"));
				res.add(temp);
			}

		} catch (Exception ex) {
			System.out.println(ex);
		}
		return res;
	}
	
	/**
	 * Devuelve un arraylist de actores cuyo apellido contenga la cadena que le pasamos
	 * @param cad cadena a buscar
	 * @return ArrayList de actores
	 */
	public List<Actor> getActors(String cad) {
		List<Actor> res = new ArrayList<Actor>();
		try {
			String sql = "select * from actor where last_name like ?";
			PreparedStatement stmt = con.prepareStatement(sql);
			stmt.setString(1, '%'+cad+'%');
			ResultSet rs = stmt.executeQuery();
			while (rs.next()) {
				Actor temp = new Actor(rs.getInt("actor_id"), rs.getString("first_name"), rs.getString("last_name"),
						rs.getDate("last_update"));
				res.add(temp);
			}

		} catch (Exception ex) {
			System.out.println(ex);
		}
		return res;
	}

	public List<Actor> getActors() {
		return getActors(max_records);
	}

	public boolean addActor(Actor actor) {
		try {
			String sql = "insert into actor (first_name, last_name) values (?,?)";
			PreparedStatement stmt = con.prepareStatement(sql);
			stmt.setString(1, actor.getFirst_name());
			stmt.setString(2, actor.getLast_name());
			int res = stmt.executeUpdate();
			return res == 1;
		} catch (Exception ex) {
			System.out.println(ex);
		}
		return false;
	}

	public boolean updateActor(Actor actor) {
		try {
			String sql = "update actor set first_name=?, last_name=? where actor_id=?";
			PreparedStatement stmt = con.prepareStatement(sql);
			stmt.setString(1, actor.getFirst_name());
			stmt.setString(2, actor.getLast_name());
			stmt.setInt(3, actor.getActor_id());
			int res = stmt.executeUpdate();
			return res == 1;
		} catch (Exception ex) {
			System.out.println(ex);
		}
		return false;
	}

	public boolean deleteActor(Actor actor) {
		try {
			if (actor != null) {
				return deleteActor(actor.getActor_id());
			}
		} catch (Exception ex) {
			System.out.println(ex);
		}
		return false;
	}

	public boolean deleteActor(int actor_id) {
		try {
			String sql = "delete from actor where actor_id=?";
			PreparedStatement stmt = con.prepareStatement(sql);
			stmt.setInt(1, actor_id);
			int res = stmt.executeUpdate();
			return res == 1;
		} catch (Exception ex) {
			System.out.println(ex);
		}
		return false;
	}

}

Podemos probarlo en el main de una clase cualquiera:

public static void main(String[] args) {
         
        // He abstraído la base de datos
        ActorDAO bd=new ActorDAO();
         
        Actor penelope=bd.getActor(1);
         
        System.out.println(penelope.getFirst_name());
 
        List<Actor> actores=bd.getActors();
        for(Actor actor:actores) {
            System.out.println(actor);
        }
         
        Actor nuevo=new Actor(1,"w","e",null);
    }

Crear una página web dinámica que use un servlet

1.- Creo un proyecto Maven con el arquetipo webapp
2.- Añado las siguientes dependencias en el POM:

	<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>6.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
		<dependency>
			<groupId>jakarta.servlet.jsp.jstl</groupId>
			<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
			<version>2.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jakarta.servlet.jsp.jstl</artifactId>
			<version>3.0.1</version>
		</dependency>

3.- Dentro de la carpeta ‘src/main’ creo una carpeta java
4.- Al crear esa carpeta nos sale arriba ‘Java Resources’
5.- Creamos ahí un paquete para poner nuestras clases. Por ejemplo ‘com.trifulcas.controller’
6.- Dentro de este paquete botón derecho ‘New->Servlet’
7.- Ponemos el enrutamiento con ‘@WebServlet(“/ruta_del_servlet”)’
8. Ejecutamos en servidor y al poner la ruta debería escribirse un mensaje que es el que tiene el servlet por defecto.

Dependencias Servlet

Tenemos que poner esto en el POM:

	<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>6.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
		<dependency>
			<groupId>jakarta.servlet.jsp.jstl</groupId>
			<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
			<version>2.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jakarta.servlet.jsp.jstl</artifactId>
			<version>3.0.1</version>
		</dependency>

https://github.com/juanpfuentes/Java/blob/main/src/java/servlet.md

JSTL:

https://www.javatpoint.com/jstl

Ejercicio mini web

Vamos a crear una miniweb con lo siguiente:

Al entrar nos aparecerá una página de login con usuario y contraseña:

Usuario:[ ]
Password:[ ]
[Enviar]

Si el usuario no es ‘admin’ ‘admin’ nos vuelve a la página de login.
Si es ‘admin’ ‘admin’ nos sale una página con estos enlaces:

Tabla de multiplicar
Numero mayor

Si pinchan en tabla de multiplicar nos sale una página con lo siguiente:
Número[ ]
[Enviar]

Si nos introducen un número en esta misma página se mostrará la tabla de multiplicar de ese número

Si pinchan en mayor nos sale una página con lo siguiente:
Número 1 [ ] Número 2 [ ]
[Enviar]
Al darle a enviar nos dice cual es el número mayor de los dos

Mejoras: que tanto en la tabla de multiplicar como en los números ya estén por defecto los valores que hemos enviado en vez de quedarse en blanco.

Ejemplos JSP

https://www3.ntu.edu.sg/home/ehchua/programming/java/JSPByExample.html

https://beginnersbook.com/jsp-tutorial-for-beginners/

https://www.javatpoint.com/jsp-tutorial

Capturar parámetros:

https://www.javatpoint.com/request-implicit-objectç

Variables de sesión:
https://www.javatpoint.com/session-implicit-object

Para declarar variables o funciones hay que usar el !:

https://www.javatpoint.com/session-implicit-object

Código de algunas páginas:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<!-- jQuery library -->
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- Popper JS -->
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

<!-- Latest compiled JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<h1>Hola Mundo!!</h1>
	<%
	out.print("<p>Vengo del código</p>");
	String nombre = "Juan";
	%>

	<p><%=nombre%></p>

	<%
	double num = Math.random();
	if (num > 0.5) {
		out.print("<h2>Ha salido cara</h2><p>crocretamente ha salido:" + num + "</p>");
	} else{
		out.print("<h2>Ha salido cruz</h2><p>crocretamente ha salido:" + num + "</p>");
	}
	if (num > 0.5) {
	%>
	<h2>Ha salido cara</h2>
	<p>
		crocretamente ha salido:
		<%=num%>
	</p>
	<%
	} else {
	%>
	<h2>Ha salido cruz</h2>
	<p>
		concretamente ha salido:
		<%=num%>#
	</p>
	<%
	}
	%>
	<button class="btn btn-primary">soy codigo</button>

</body>
</html>
	<!-- Imprimo con la función out de JSP -->
	<p>
		<%
		out.print("Esto es código JSP");
		%>
	</p>

	<!-- %= es un atajo si solo quiero imprimir -->
	<p><%="Esto es también"%></p>

	<!-- Uso clases de java -->
	<h3><%=java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("dd-MM-yyy HH:mm"))%></h3>


	<!-- Declaraciones -->
	<%!String nombre = "Ana Pi";

	String saludo(String nombre) {
		return "Hola " + nombre;
	}%>

	<!-- Uso lo declarado -->

	<p><%=saludo(nombre)%></p>
	<p><%=saludo("Juan Buj")%></p>

Conexión base de datos

Para conectarnos desde java a las bases de datos tenemos varias opciones. Empezaremos con la más sencilla y en días sucesivos veremos otras más complejas.

En un proyecto Java podemos añadir el conector mysql. Primero lo tenemos que descargar, si queréis lo podéis hacer desde aquí:

https://github.com/juanpablofuentes/JavaNetmind/tree/main/MiPrimerProyecto/src

https://dev.mysql.com/downloads/connector/j/

Botón derecho guardar archivo mysql connector

Creamos un nuevo proyecto (para no mezclar) y añadimos este jar a las librerías de nuestro proyecto. Un manual:

https://www.knowprogram.com/jdbc/connect-mysql-database-eclipse/

Una vez lo tengamos añadido podemos conectarnos a nuestra base de datos con la cadena de conexión, de manera parecida a como lo hacemos en el workbench, indicando la url del servidor, la base de datos, y el usuario y la contraseña:

	Class.forName("com.mysql.cj.jdbc.Driver");
			Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sakila", "root", "");

A partir de aquí podemos acceder a la base de datos:


Statement stmt = con.createStatement();
			ResultSet rs = stmt.executeQuery("select * from actor");
			while (rs.next()) {
				System.out.println(rs.getInt(1) + "  " + rs.getString(2) + "  " + rs.getString(3));
			}
			rs = stmt.executeQuery("select * from actor");
			while (rs.next()) {
				System.out.println(
						rs.getInt("actor_id") + "  " + rs.getString("first_name") + "  " + rs.getString("last_name"));
			}

			int result=stmt.executeUpdate("insert into actor (first_name, last_name) values ('Eva','Pi')");  
			System.out.println(result+" filas afectadas");

			PreparedStatement ps = con.prepareStatement("select * from actor where first_name like ?");
			ps.setString(1, "%ar%");
			rs = ps.executeQuery();
			while (rs.next()) {
				System.out.println(
						rs.getInt("actor_id") + "  " + rs.getString("first_name") + "  " + rs.getString("last_name"));
			}