Muestre JDBC ResultSet en HTML en la página JSP usando el patrón MVC y DAO

Resuelto Ashwani Sharma asked hace 13 años • 0 respuestas

Estoy implementando MVC usando JSP y JDBC. Importé un archivo de clase de base de datos a mi archivo JSP y me gustaría mostrar los datos de una tabla de base de datos. No sé cómo debo devolver la ResultSetclase Java a la página JSP e incrustarla en HTML.

¿Cómo puedo conseguir esto?

Ashwani Sharma avatar Feb 15 '11 18:02 Ashwani Sharma
Aceptado

En un enfoque MVC bien diseñado, el archivo JSP no debe contener ninguna línea de código Java y la clase de servlet no debe contener ninguna línea de código JDBC.

Suponiendo que desea mostrar una lista de productos en una tienda web, debe crear el siguiente código.

  • Una Productclase que representa una entidad de un producto del mundo real, debería ser simplemente un Javabean .

    public class Product {
    
        private Long id; 
        private String name;
        private String description;
        private BigDecimal price;
    
        // Add/generate getters/setters/c'tors/equals/hashcode boilerplate.
    }
    
  • Una clase DAO que hace todo el trabajo desagradable de JDBC y devuelve un bonito archivo List<Product>.

    public class ProductDAO {
    
        private DataSource dataSource;
    
        public ProductDAO(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public List<Product> list() throws SQLException {
            List<Product> products = new ArrayList<Product>();
    
            try (
                Connection connection = dataSource.getConnection();
                PreparedStatement statement = connection.prepareStatement("SELECT id, name, description, price FROM product");
                ResultSet resultSet = statement.executeQuery();
            ) {
                while (resultSet.next()) {
                    Product product = new Product();
                    product.setId(resultSet.getLong("id"));
                    product.setName(resultSet.getString("name"));
                    product.setDescription(resultSet.getString("description"));
                    product.setPrice(resultSet.getBigDecimal("price"));
                    products.add(product);
                }
            }
    
            return products;
        }
    
    }
    
  • Una clase de servlet que obtiene la lista y la coloca en el ámbito de la solicitud.

    @WebServlet("/products")
    public class ProductsServlet extends HttpServlet {
    
        @Resource(name="jdbc/YourDB") // For Tomcat, define as <Resource> in context.xml and declare as <resource-ref> in web.xml.
        private DataSource dataSource;
        private ProductDAO productDAO;
    
        @Override
        public void init() {
            productDAO = new ProductDAO(dataSource);
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            try {
                List<Product> products = productDAO.list();
                request.setAttribute("products", products); // Will be available as ${products} in JSP
                request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
            } catch (SQLException e) {
                throw new ServletException("Cannot obtain products from DB", e);
            }
        }
    
    }
    
  • Finalmente, un archivo JSP/WEB-INF/products.jsp en el que se utiliza JSTL <c:forEach> para iterar sobre List<Product>lo que está disponible en EL mediante ${products}, y se utiliza JSTL <c:out>para escapar de las propiedades de la cadena a fin de evitar agujeros XSS cuando se trata de entradas controladas por el usuario.

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/format" prefix="fmt" %>
    ...
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td>${product.id}</td>
                <td><c:out value="${product.name}" /></td>
                <td><c:out value="${product.description}" /></td>
                <td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
            </tr>
        </c:forEach>
    </table>
    

Para que funcione, simplemente llame al servlet por su URL. Siempre que el servlet esté anotado @WebServlet("/products")o asignado web.xmlcon <url-pattern>/products</url-pattern>, puede llamarlo mediantehttp://example.com/contextname/products

Ver también:

  • ¿Cómo evitar el código Java en archivos JSP?
  • doGet y doPost en Servlets
  • ¿Cómo debo conectarme a la base de datos/fuente de datos JDBC en una aplicación basada en servlet?
  • Patrones de diseño de aplicaciones basadas en web.
  • RequestDispatcher.forward() frente a HttpServletResponse.sendRedirect()
  • ¿Cómo asignar un conjunto de resultados con una cantidad desconocida de columnas a una lista y mostrarlo en una tabla HTML?
  • ¿Cómo paso el elemento actual al método Java haciendo clic en un hipervínculo o botón en la página JSP?
BalusC avatar Feb 15 '2011 12:02 BalusC

MVC, en el contexto de una aplicación web, no consiste en utilizar una clase de un JSP. Consiste en utilizar el siguiente modelo:

  1. El navegador envía una solicitud a un servidor web.
  2. el servidor web está configurado para que la solicitud sea manejada por un servlet o un filtro (el controlador: código Java, no código JSP)
  3. El servlet/filtro generalmente envía la solicitud a una clase específica (llamada Acción, la parte específica del controlador), según la configuración/anotaciones.
  4. La acción ejecuta la lógica de negocios (es decir, recupera los datos de la base de datos en su ejemplo: el modelo)
  5. La acción reenvía la solicitud a un JSP. La función del JSP es únicamente generar código HTML (es decir, mostrar sus datos: la vista)

Dado que JSP generalmente usa etiquetas JSP (JSTL, por ejemplo) y el lenguaje de expresión JSP, y dado que las etiquetas JSP y EL están diseñados para obtener información de JavaBeans, será mejor que tenga sus datos disponibles en forma de JavaBeans o colecciones. de JavaBeans.

La función del controlador (la clase de acción) es, por tanto, recuperar los datos, crear instancias de JavaBean que contengan los datos, en un formato adecuado para el JSP, colocarlos en atributos de solicitud y luego enviarlos al JSP. Luego, JSP iterará a través de las instancias de JavaBean y mostrará lo que contienen.

No debes implementar el marco MVC tú mismo. Utilice los existentes (Stripes, Struts, etc.)

JB Nizet avatar Feb 15 '2011 11:02 JB Nizet

No sé cómo debo devolver el ResultSet del archivo de clase a la página JSP

Bueno, no lo haces.

El objetivo de MVC es separar su modelo (la información de M DB en este caso) de su vista ( V a jsp, en este caso) de tal manera que pueda cambiar la vista sin tener que frenar la aplicación.

Para hacer esto, puede usar un objeto intermedio para representar sus datos (generalmente llamado DTO, después de Data Transfer Object, no sé cómo lo llaman hoy en día) y otro objeto para recuperarlos (generalmente un DAO).

Básicamente, tiene su archivo JSP, obtiene los parámetros de solicitud y luego invoca un método desde DAO. El dao, internamente, tiene los medios para conectarse a la base de datos y recuperar los datos y crea colecciones de DTO que se devuelven al JSP para su procesamiento.

Algo como este código extremadamente simplificado (e inseguro):

Empleado.java

class Employee {
   String name;
   int emplid;
}

EmpleadoDAO.java

class EmployeeDAO { 
   ... method to connect 
   etc. 
   List<Employee> getAllNamed( String name ) { 
       String query = "SELECT name, emplid FROM employee where name like ?";
       ResultSet rs = preparedStatement.executeQuery etc etc.
       List<Employee> results = ....
       while( rs.hasNext() ) { 
          results.add( new Employee( rs.getString("name"), rs.getInt("emplid")));
       }
       // close resources etc 
       return results;
    }
}

empleado.jsp

<%
   request.setAttribute("employees", dao.getAllNamed( request.getParameter("name") );
%>
<table>
<c:forEach items="${employees}" var="employee">
<tr><td>${employee.emplid}</td><td>${employee.name}</td></tr>
</c:forEach>
</table>

Espero que esto te dé una mejor idea.

OscarRyz avatar Feb 15 '2011 12:02 OscarRyz