Показать JDBC ResultSet в HTML на странице JSP с использованием шаблона MVC и DAO
Я реализую MVC с использованием JSP и JDBC. Я импортировал файл класса базы данных в мой файл JSP и хотел бы показать данные таблицы БД. Я не знаю, как я должен вернуть ResultSet
из класса Java на страницу JSP и встраивать его в HTML.
Как мне этого добиться?
6 ответов
В хорошо разработанном подходе MVC файл JSP не должен содержать какой-либо строки кода Java, а класс сервлета не должен содержать какой-либо строки кода JDBC.
Предполагая, что вы хотите показать список товаров в интернет-магазине, необходимо создать следующий код.
Product
класс, представляющий сущность продукта реального мира, это должен быть просто 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. }
Класс DAO, который выполняет всю неприятную работу JDBC и возвращает хороший
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; } }
Класс сервлета, который получает список и помещает его в область запроса.
@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); } } }
Наконец файл JSP в
/WEB-INF/products.jsp
который использует JSTL<c:forEach>
перебиратьList<Product>
который доступен в EL${products}
и использует JSTL<c:out>
чтобы избежать строковых свойств, чтобы избежать дыр в XSS, когда это касается ввода, управляемого пользователем.<%@ 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>
Чтобы заставить его работать, просто вызовите сервлет по его URL. При условии, что сервлет аннотирован @WebServlet("/products")
или отображается в web.xml
с <url-pattern>/products</url-pattern>
тогда вы можете позвонить по http://example.com/contextname/products
Смотрите также:
- Как избежать Java-кода в файлах JSP?
- doGet и doPost в сервлетах
- Как подключиться к базе данных / источнику данных JDBC в приложении на основе сервлета?
- Шаблоны проектирования веб-приложений
- RequestDispatcher.forward() против HttpServletResponse.sendRedirect()
- Как сопоставить ResultSet с неизвестным количеством столбцов в List и отобразить его в таблице HTML?
- Как передать текущий элемент методу Java, нажав гиперссылку или кнопку на странице JSP?
MVC в контексте веб-приложения не состоит в использовании класса из JSP. Он заключается в использовании следующей модели:
- браузер отправляет запрос на веб-сервер
- веб-сервер настроен так, что запрос обрабатывается сервлетом или фильтром (контроллер: код Java, а не код JSP)
- Сервлет / фильтр обычно отправляет запрос определенному классу (называемому Action, определенной частью контроллера) на основе конфигурации / аннотаций
- Действие выполняет бизнес-логику (т.е. извлекает данные из базы данных в вашем примере: модель)
- Действие перенаправляет запрос в JSP. Роль JSP заключается только в том, чтобы генерировать HTML-код (т.е. отображать ваши данные: представление)
Поскольку JSP обычно использует теги JSP (например, JSTL) и язык выражений JSP, а теги JSP и EL предназначены для получения информации из JavaBeans, вам лучше иметь свои данные доступными в форме JavaBeans или коллекций JavaBeans.
Таким образом, роль контроллера (класса действия) заключается в извлечении данных, создании экземпляров JavaBean, содержащих данные, в подходящем формате для JSP, их размещении в атрибутах запроса и последующей отправке в JSP. Затем JSP будет перебирать экземпляры JavaBean и отображать их содержимое.
Вы не должны реализовывать MVC-фреймворк самостоятельно. Использовать уже существующие (Stripes, Struts и т. Д.)
Я не знаю, как мне вернуть ResultSet из файла класса на страницу JSP
Ну, ты не.
Смысл MVC состоит в том, чтобы отделить вашу модель (в данном случае информацию о M DB) от вашего представления (в данном случае V a jsp) таким образом, чтобы вы могли изменить представление без торможения для приложения.
Для этого вы можете использовать промежуточный объект для представления ваших данных (обычно называемый DTO - после Data Transfer Object - не знаю, как они его называют в наши дни) и другой объект для его извлечения (обычно DAO).
Таким образом, у вас есть файл JSP, вы получаете параметры запроса и затем вызываете метод из DAO. Внутренний dao имеет средства для подключения к базе данных и извлечения данных и создает коллекции DTO, которые возвращаются в JSP для рендеринга.
Примерно такой чрезвычайно упрощенный (и небезопасный) код:
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>
Я надеюсь, что это даст вам лучшую идею.
У меня проблема. Я не понимаю четко код. У меня похожая проблема с моим кодом.
Я создал базу данных SQL и заполнил. Затем я хочу реализовать MainServlet (код ниже), который получает данные из базы данных и на другой странице jsp, я хочу вставить эти данные в раздел, например h1, h2 и т. Д. ... Я должен использовать синтаксис ${}, но я не не знаю, как это сделать.
Вкратце, в файле jsp (код ниже, я ДОЛЖЕН ИСПОЛЬЗОВАТЬ ${} SINTAX) я хочу «вызвать» MainServlet, и там я хочу получить данные из базы данных и просмотреть в файле jsp.
Надеюсь правильно объяснил, большое спасибо!
MainServlet.java
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MainServlet
*/
@WebServlet({ "/MainServlet" })
public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String PATH_JSP = "/WEB-INF/";
/**
* @see HttpServlet#HttpServlet()
*/
public MainServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String doveAndare = request.getParameter("azione");
if(doveAndare==null)
doveAndare = "index";
try {
String driverString = "com.mysql.cj.jdbc.Driver";
Class.forName(driverString);
String connString = "jdbc:mysql://localhost:3306/ldd_jewels?user=root&password=";
Connection conn = DriverManager.getConnection(connString);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM JEWEL");
while (rs.next() == true) {
System.out.println(rs.getString("Category") + "\t" + rs.getString("Name"));
/* I try that but does not work
request.setAttribute("name", rs.getString("Name"));
javax.servlet.RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/widering_male.jsp");
dispatcher.forward(request, response); */
}
stmt.close();
conn.close();
} catch(Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(PATH_JSP+doveAndare+".jsp").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
doublerow.jsp
<section id="portfolio-details" class="portfolio-details">
<div class="container">
<div class="row gy-4">
<div class="col-lg-8">
<div class="portfolio-details-slider swiper">
<div class="swiper-wrapper align-items-center">
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_1.jpg" alt="" />
</div>
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_2.jpg" alt="" />
</div>
<div class="swiper-slide">
<img src="assets/img/jewels/doublerow_3.jpg" alt="" />
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
<div class="col-lg-4">
<div class="portfolio-info">
<h3>Product details</h3>
<ul>
<li><strong>Code</strong>: 1S3D5</li>
<li><strong>Category</strong>: Bracelets</li>
<li><strong>Name</strong>: Double Row Hinged Bangle</li>
<li><strong>Gender</strong>: Female</li>
<li><strong>Material</strong>: Yellow gold</li>
<li><strong>Size</strong>: 121mm</li>
<li><strong>Price</strong>: €5500</li>
</ul>
</div>
<div class="portfolio-description">
<h2>Description of product</h2>
<p>
The entwined ends of Tiffany Knot’s signature motif symbolize
the power of connections between people. Balancing strength
and elegance, each Tiffany Knot design is a complex feat of
craftsmanship. This bangle is crafted with yellow gold and
polished by hand for high shine. Wear on its own or partnered
with classic silhouettes for an unexpected pairing.
</p>
</div>
</div>
</div>
</div>
</section>
Это моя база данных: я хочу вставить каждый драгоценный камень на разные страницы (у каждого драгоценного камня есть файл jsp)
Вы можете использовать <c:forEach >
тег
Вы можете найти подробный пример в следующем примере использования ссылки
Я думаю, что для вас будет лучше поместить данные таблицы в коллекцию, такую как list, и вернуть список из класса Java и повторно использовать эту коллекцию в JSP.