J'implémente MVC en utilisant JSP et JDBC. J'ai importé un fichier de classe de base de données dans mon fichier JSP et je voudrais afficher les données d'une table DB. Je ne sais pas comment renvoyer le ResultSet
de la classe Java à la page JSP et l'intégrer au format HTML.
Comment puis-je atteindre cet objectif?
Dans une approche MVC bien conçue, le fichier JSP ne doit contenir aucune ligne de code Java et la classe de servlet ne doit contenir aucune ligne de code JDBC.
En supposant que vous souhaitez afficher une liste de produits dans une boutique en ligne, le code suivant doit être créé.
Une classe Product
représentant une entité réelle d'un produit, elle devrait être juste 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.
}
Une classe DAO qui fait tout le méchant travail JDBC et renvoie un joli 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;
}
}
Une classe servlet qui obtient la liste et la place dans la portée de la requête.
@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);
}
}
}
Enfin un fichier JSP dans /WEB-INF/products.jsp
Qui utilise JSTL <c:forEach>
Pour itérer sur List<Product>
Qui est disponible dans EL par ${products}
, Et utilise JSTL <c:out>
Pour échapper aux propriétés des chaînes afin d'éviter les trous XSS lorsqu'il s'agit d'une entrée contrôlée par l'utilisateur.
<%@ 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>
Pour le faire fonctionner, il suffit d'appeler le servlet par son URL. À condition que le servlet soit annoté @WebServlet("/products")
ou mappé dans web.xml
Avec <url-pattern>/products</url-pattern>
, Vous pouvez l'appeler par http://example.com/contextname/products
MVC, dans un contexte d'application web, ne consiste pas à utiliser une classe à partir d'une JSP. Il consiste à utiliser le modèle suivant:
Étant donné que le JSP utilise généralement des balises JSP (le JSTL, par exemple) et le langage d'expression JSP, et puisque les balises JSP et l'EL sont conçues pour obtenir des informations à partir de JavaBeans, vous feriez mieux d'avoir vos données disponibles sous la forme de JavaBeans ou de collections de JavaBeans.
Le rôle du contrôleur (la classe d'action) est donc de récupérer les données, de créer des instances JavaBean contenant les données, dans un format approprié pour le JSP, de les mettre dans des attributs de requête, puis de les envoyer au JSP. Le JSP va ensuite parcourir les instances JavaBean et afficher ce qu'elles contiennent.
Vous ne devez pas implémenter le framework MVC vous-même. Utilisez ceux existants (Stripes, Struts, etc.)
Je ne sais pas comment retourner le ResultSet du fichier de classe à la page JSP
Eh bien non.
Le point de MVC est de séparer votre modèle (le M DB info dans ce cas) de votre vue ( V a jsp, dans ce cas) de telle manière que vous pouvez changer la vue sans freiner l'application.
Pour ce faire, vous pouvez utiliser un objet intermédiaire pour représenter vos données (généralement appelé DTO - après Data Transfer Object -, je ne sais pas comment ils l'appellent de nos jours), et un autre objet pour le récupérer (généralement un DAO).
Donc, fondamentalement, vous avez votre fichier JSP, obtenez les paramètres de demande, puis appelez une méthode à partir du DAO. Le dao, en interne, a les moyens de se connecter à la base de données et de récupérer les données et construit une collection de DTO qui sont retournés au JSP pour le rendu.
Quelque chose comme ce code extrêmement simplifié (et non sécurisé):
Employee.Java
class Employee {
String name;
int emplid;
}
EmployeeDAO.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;
}
}
employee.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>
J'espère que cela vous donnera une meilleure idée.