Показать 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

Смотрите также:

MVC в контексте веб-приложения не состоит в использовании класса из JSP. Он заключается в использовании следующей модели:

  1. браузер отправляет запрос на веб-сервер
  2. веб-сервер настроен так, что запрос обрабатывается сервлетом или фильтром (контроллер: код Java, а не код JSP)
  3. Сервлет / фильтр обычно отправляет запрос определенному классу (называемому Action, определенной частью контроллера) на основе конфигурации / аннотаций
  4. Действие выполняет бизнес-логику (т.е. извлекает данные из базы данных в вашем примере: модель)
  5. Действие перенаправляет запрос в 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.

Другие вопросы по тегам