web-dev-qa-db-ja.com

MVCおよびDAOパターンを使用して、JSPページのHTMLでJDBC ResultSetを表示する

JSPとJDBCを使用してMVCを実装しています。データベースクラスファイルをJSPファイルにインポートしました。DBテーブルのデータを表示したいと思います。 ResultSetをJavaクラスからJSPページに返し、HTMLに埋め込む方法はわかりません。

どうすればこれを達成できますか?

51
Ashwani Sharma

適切に設計されたMVCアプローチでは、JSPファイルにJavaコードの行を含めないでください。また、サーブレットクラスにJDBCコードの行を含めないでください。

Webショップで製品のリストを表示する場合、次のコードを作成する必要があります。

  • 製品の実世界のエンティティを表す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作業をすべて実行し、Nice 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;
        }
    
    }
    
  • リストを取得して要求スコープに入れる servlet クラス。

    @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);
            }
        }
    
    }
    
  • 最後に、 [〜#〜] jstl [〜#〜]/WEB-INF/products.jspを使用する<c:forEach>[〜#〜] jsp [〜#〜] ファイルList<Product>によって [〜#〜] el [〜#〜] で利用可能になり、JSTL ${products}を使用して回避するために文字列プロパティをエスケープする<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で呼び出すことができます。

こちらもご覧ください:

118
BalusC

WebアプリケーションのコンテキストでのMVCは、JSPのクラスを使用することではありません。次のモデルを使用することで構成されています。

  1. ブラウザはWebサーバーにリクエストを送信します
  2. webサーバーは、リクエストがサーブレットまたはフィルターによって処理されるように構成されます(コントローラー:Javaコード)
  3. 通常、サーブレット/フィルターは、構成/注釈に基づいて、特定のクラス(コントローラーの特定の部分であるアクションと呼ばれる)に要求をディスパッチします。
  4. アクションはビジネスロジックを実行します(例では、データベースからデータを取得します:モデル)
  5. アクションはリクエストをJSPに転送します。 JSPの役割は、HTMLコードを生成することだけです(つまり、データの表示:ビュー)

JSPは通常、JSPタグ(JSTLなど)とJSP式言語を使用するため、JSPタグとELはJavaBeansから情報を取得するように設計されているため、JavaBeansまたはコレクションの形式でデータを利用できるようにする方がよいJavaBeansの。

したがって、コントローラー(アクションクラス)の役割は、データを取得し、JSPに適した形式でデータを含むJavaBeanインスタンスを作成し、それらをリクエスト属性に入れてから、JSPにディスパッチすることです。次に、JSPはJavaBeanインスタンスを反復処理し、それらに含まれる内容を表示します。

MVCフレームワークを自分で実装しないでください。既存のもの(ストライプ、ストラットなど)を使用する

11
JB Nizet

ResultSetをクラスファイルからJSPページに返す方法がわからない

まあ、あなたはしません。

[〜#〜] mvc [〜#〜]のポイントは、モデルを分離することです([〜#〜] m [〜#〜]この中のDB情報case)あなたのビューから([〜#〜] v [〜#〜] jsp、この場合)あなたがアプリケーションにブレーキをかけずにビューを変更できるような方法で。

これを行うには、中間オブジェクトを使用してデータを表すことがあります(通常、データ転送オブジェクトの後にDTOと呼ばれますが、最近の呼び出し方法がわかりません)、および他のオブジェクト(通常はDAO)を取得します。

基本的に、JSPファイルを用意し、リクエストパラメータを取得してから、DAOからメソッドを呼び出します。 daoは、内部的にdbに接続してデータを取得し、レンダリングのためにJSPに返されるDTOのコレクションを構築する手段を備えています。

このような非常に単純化された(そして安全でない)コードのようなもの:

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>

これにより、より良いアイデアが得られることを願っています。

5
OscarRyz