Programación

1º DAM/DAW - Curso 2023-2024

User Tools

Site Tools


apuntes:web

This is an old revision of the document!


Creación de una aplicación web

Creación del proyecto

Estructura del proyecto

Figure 1: Estructura de un proyecto JSP

Dependencias

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
 
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>
 
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.26</version>
</dependency>
 
<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-core</artifactId>
    <version>3.37.1</version>
</dependency>
 
<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-sqlobject</artifactId>
    <version>3.37.1</version>
</dependency>

Ficheros de configuración del proyecto

context.xml
<?xml version="1.0" encoding="UTF-8" ?>
<Context path="/amazon"/>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
 
<web-app>
  <display-name>Amazon web application</display-name>
</web-app>

Base de datos

CREATE TABLE activities (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) UNIQUE NOT NULL,
  description VARCHAR(250),
  datetime DATETIME,
  price FLOAT,
  picture VARCHAR(50)
);
 
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL DEFAULT 'no-name',
  username VARCHAR(50) UNIQUE NOT NULL,
  password VARCHAR(40) NOT NULL,
  ROLE VARCHAR(50) DEFAULT 'user'
);

Creación de una página JSP

Creación de un Servlet

Crear un formulario para registrar información

Formulario JSP

<section class="py-5 container">
  <h1>Registrar nueva Actividad</h1>
  <h1>Modificar Actividad</h1>
  <form class="row g-3 needs-validation" method="post" enctype="multipart/form-data" id="edit-form">
    <div class="mb-3">
      <label for="name" class="form-label">Nombre</label>
      <input type="text" name="name" class="form-control" id="name" placeholder="Ir a caminar"
    </div>
    <div class="mb-3">
      <label for="description" class="form-label">Descripción</label>
      <textarea rows="4" name="description" cols="50" class="form-control" id="description" placeholder="Descripción de la actividad"></textarea>
    </div>
    <div class="col-md-4">
      <label for="date" class="form-label">Fecha</label>
      <input type="date" name="date" class="form-control" id="date" placeholder="dd/mm/yyyy"
    </div>
    <div class="col-md-4">
      <label for="price" class="form-label">Precio</label>
      <input type="text" name="price" class="form-control" id="price" placeholder="15,00"
    </div>
    <div class="col-md-4">
      <label for="picture" class="form-label">Foto</label>
      <input type="file" name="picture" class="form-control" id="picture">
    </div>
    <div class="col-12">
      <input type="submit" value="Enviar" id="edit-button"/>
    </div>
    <input type="hidden" name="id" value="<%= id %>"/>
  </form>
  <br/>
  <div id="result"></div>
</section>

Servlet para procesar la información

@WebServlet("/edit-activity")
@MultipartConfig
public class EditActivity extends HttpServlet {
 
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
 
    HttpSession currentSession = request.getSession();
    if (currentSession.getAttribute("role") != null) {
      if (!currentSession.getAttribute("role").equals("admin")) {
        response.sendRedirect("/parque");
      }
    }
 
    try {
      if (hasValidationErrors(request, response))
        return;
 
      int id = 0;
      if (request.getParameter("id") != null) {
        id = Integer.parseInt(request.getParameter("id"));
      }
 
      String name = request.getParameter("name");
      String description = request.getParameter("description");
      Date date = DateUtils.parse(request.getParameter("date"));
      float price = CurrencyUtils.parse(request.getParameter("price"));
      Part picturePart = request.getPart("picture");
 
      // Guardar la imagen en disco
      String imagePath = request.getServletContext().getInitParameter("image-path");
      String filename = null;
      if (picturePart.getSize() == 0) {
        filename = "no-image.jpg";
      } else {
        filename = UUID.randomUUID() + ".jpg";
        InputStream fileStream = picturePart.getInputStream();
        Files.copy(fileStream, Path.of(imagePath + File.separator + filename));
      }
 
      Database.connect();
      final String finalFilename = filename;
      if (id == 0) {
        int affectedRows = Database.jdbi.withExtension(ActivityDao.class,
           dao -> dao.addActivity(name, description, date, price, finalFilename));
        sendMessage("Actividad registrada correctamente", response);
      } else {
        final int finalId = id;
        int affectedRows = Database.jdbi.withExtension(ActivityDao.class,
          dao -> dao.updateActivity(name, description, date, price, finalFilename, finalId));
        sendMessage("Actividad modificada correctamente", response);
      }
    } catch (ParseException pe) {
      pe.printStackTrace();
      sendError("El formato de fecha o precio no es correcto", response);
    } catch (ClassNotFoundException cnfe) {
      cnfe.printStackTrace();
      sendError("Internal Server Error", response);
    } catch (SQLException sqle) {
      sqle.printStackTrace();
      sendError("Error conectando con la base de datos", response);
    }
  }
 
  private boolean hasValidationErrors(HttpServletRequest request, HttpServletResponse response) throws IOException {
    boolean hasErrors = false;
 
    if (request.getParameter("name") == null) {
      sendError("El nombre es un campo obligatorio", response);
      hasErrors = true;
    }
    try {
      DateUtils.parse(request.getParameter("date"));
    } catch (ParseException pe) {
      sendError("Formato de fecha no válido", response);
      hasErrors = true;
    }
    try {
      float priceValue = CurrencyUtils.parse(request.getParameter("price"));
    } catch (ParseException pe) {
      sendError("Formato de precio no válido", response);
      hasErrors = true;
    }
 
    return hasErrors;
  }
}

Envío asíncrono del formulario

<script>
  $(document).ready(function () {
    $("#edit-button").click(function (event) {
      event.preventDefault();
      const form = $("#edit-form")[0];
      const data = new FormData(form);
 
      $("#edit-button").prop("disabled", true);
        $.ajax({
          type: "POST",
          enctype: "multipart/form-data",
          url: "edit-activity",
          data: data,
          processData: false,
          contentType: false,
          cache: false,
          timeout: 600000,
          success: function (data) {
            $("#result").html(data);
            $("#edit-button").prop("disabled", false);
          },
          error: function (error) {
            $("#result").html(error.responseText);
            $("#edit-button").prop("disabled", false);
          }
       });
    });
  });
</script>

Crear una página JSP para mostrar información

JSTL: JavaServer Pages Standard Tag Library

<dependencies>
  . . .
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
  </dependency>
  . . .
</dependencies>
. . .
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
. . .
<%
  . . .
  pageContext.setAttribute("nombreAtributo", "valorAtributo");
  . . .
%>
. . .
<c:out value="${nombreAtributo}"/>
. . .
. . .
<c:if test="${nombreAtributo=='valorAtributo'}">
  <c:out value="El atributo 'nombreAtributo' es igual a 'valorAtributo'"/>
</c:if>
. . .

Uso de sesiones. Login y área privada

Inicio de sesión. Login

login.jsp
. . .
<script type="text/javascript">
  $(document).ready(function() {
    $("form").on("submit", function(event) {
      event.preventDefault();
      const formValue = $(this).serialize();
      $.ajax("login", {
        type: "POST",
        data: formValue,
        statusCode: {
          200: function(response) {
            if (response === "ok") {
              window.location.href = "/parque";
            } else {
              $("#result").html(response);
            }
          }
        }
      });
    });
  });
</script>
. . .
login.jsp
<main class="form-signin w-100 m-auto">
  <form>
    <h1 class="h3 mb-3 fw-normal">Iniciar sesión</h1>
    <div class="form-floating">
      <input type="text" name="username" class="form-control" id="floatingInput" placeholder="Usuario">
      <label for="floatingInput">Usuario</label>
    </div>
    <div class="form-floating">
      <input type="password" name="password" class="form-control" id="floatingPassword" placeholder="Contraseña">
      <label for="floatingPassword">Contraseña</label>
    </div>
 
    <button class="btn btn-primary w-100 py-2" type="submit">Iniciar sesión</button>
  </form>
  <br/>
  <div id="result"></div>
</main>
. . .
LoginServlet.java
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
 
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
 
    String username = request.getParameter("username");
    String password = request.getParameter("password");
 
    try {
      Database.connect();
      User user = Database.jdbi.withExtension(UserDao.class,
        dao -> dao.getUser(username, password));
      if (user != null) {
        HttpSession session = request.getSession();
        session.setAttribute("username", user.getUsername());
        session.setAttribute("role", user.getRole());
        response.getWriter().print("ok");
      } else {
        sendError("El usuario no existe", response);
      }
    } catch (ClassNotFoundException cnfe) {
      cnfe.printStackTrace();
      sendError("Internal Server Error", response);
    } catch (SQLException sqle) {
      sqle.printStackTrace();
      sendError("Error conectando con la base de datos", response);
    }
  }
}

Mantenimiento de la sesión


© 2023-2024 Santiago Faci

apuntes/web.1711887999.txt.gz · Last modified: 2024/03/31 12:26 by Santiago Faci