Java Solaris 加入Sun中国技术社区 我的社区 注册说明
 
JDK 6.0 API 中文版
 
 
 
 
Java API 文档中文版
使用 MySQL 在 NetBeans IDE 中创建一个简单的 Web 应用程序
 
By Troy Giunipero, 3/27/08  

本文将介绍如何创建一个简单的分布式 Web 应用程序,并将它连接到 MySQL 数据库。同时还将介绍 Web 开发中的一些基本概念和技术,比如 Java Server Pages(JSP)和三层架构。本教程适用于掌握 Java 编程和 Web 开发基础知识且有意应用 MySQL 技能的初学者。

MySQL 是一个流行的开源数据库管理系统,得益其速度、灵活性和可靠性,因而通常用于 Web 应用程序。MySQL 使用 SQL(或者结构化查询语言)访问和处理数据库中包含的数据。

本教程是 连接 MySQL 数据库 这篇文章的扩展,并且假设您已经与在 NetBeans IDE 中创建和配置的 MySQL 数据库建立了连接。本教程也需要在 ifpwafcad.sql. 中包含的表数据。此SQL文件创建两个表,Counselor Subject,然后使用示例数据对其进行填充。将此文件保存到一个本地目录,然后在NetBeans中打开并在MySQL数据库上运行。在本教程中,我们使用的数据库为 MyNewDatabase

 

预计时间:40 分钟

 

本文涵盖以下主题:

 

获取软件

开始之前,请确保已在计算机上安装以下软件:

  • NetBeans IDE 5.5(下载
  • Java SE Development Kit (JDK™) 5.0 版或更高版本(下载)
  • MySQL 数据库(下载
  • MySQL 的 JDBC 驱动(下载
  • Sun Java System Application Server(下载

注意:本教程并不一定需要 Sun Java System Application Server (SJSAS),因为您也可以使用 Tomcat,它是一种与 NetBeans IDE 绑定的Web 服务器。但是,如果您要在 IDE 中开发应用程序,该应用程序服务器提供很多对工具和技术的支持,可方便开发人员。注意下载 Java EE 5工具包,其中包含 SJSAS、NetBeans IDE 以及 Java SE Development Kit。访问 SJSAS 产品页面 获得更多信息。

 

计划结构

示例 Web 应用程序通常使用三层架构设计,在三层架构中,用户界面、功能进程逻辑以及数据访问和存储都是彼此独立运作的。换句话说,三层(tier 或 layer)中的每一层都表示一个可以在其自己的平台上运行的模块(因此有术语“分布式”)。

对于在本教程中构建的应用程序,表示层(或用户界面)可以由 JSP 页面表示,它准备发送到客户端浏览器的 HTML。您可以使用一些示例 Java 类来编码中间(或逻辑)层。最后,数据层可以使用 MySQL 数据库中的一些表来实现。考虑以下客户端-服务器方案:

描述示例Web应用程序的结构的图表

 

浏览器中显示欢迎页面(index.jsp),其中包含一个允许访问者指定数据的简单表单。当请求被发送到包含数据的 JSP 页面后,JSP 页面(response.jsp)被访问,该页面立即将指定的数据发送到 SubjectCounselor.java,这样就可以开始信息查询进程。该 Java 类处理数据并采用 AccessDB.java,以准备将被发送到数据库的 SQ L查询。然后 AccessDB.java 连接到数据库,随后按照 SQL 查询的指定从 Subject Counselor 表中检索数据。最后,启动回程,检索的数据包含在 response.jsp 中,它会构建服务器对客户端的响应。

 

创建新项目

为了实现以上描述的方案,您将为一个假想的组织 IFPWAFCAD(或 International Former Professional Wrestlers' Association for Counseling and Development)开发一个简单的应用程序。该应用程序使用户可以从下拉列表(index.jsp)中选择一个咨询主题,然后从 MySQL 数据库中检索数据,并将信息返回给用户(response.jsp):

index.jsp response.jsp
index.jsp displayed in a browser response.jsp displayed in a browser

 

通过执行以下步骤在 IDE 中创建一个新项目:

  1. 通过 File 菜单启动 NetBeans IDE 并选择 New Project (Ctrl+Shift+N)。在 Categories 下选择 Web;在 Projects 下选择 Web Application。单击 Next 按钮。
  2. 在 Project Name 中输入 IFPWAFCAD。从 Server 下拉列表中,选择您计划使用的服务器。其余设置保持默认并单击 Finish 按钮。

    注意:如果您下载了 SJSAS,但是还没有在 NetBeans IDE 中注册,你可以通过单击 Server 下拉列表右侧的 Manage 按钮来进行注册。Server Manager 即会打开,使您可以注册新服务器。有关更多信息,请参考 IDE 的“帮助目录”(F1)中的 Registering a Sun Java System Application Server Instance(注册一个 Sun Java 系统应用程序服务器实例)。

    IDE 为整个应用程序创建一个项目模板,并且在 Source Editor 中打开一个空的 JSP 页面(index.jsp)。要更好地理解该项目模板的结构,请参考 IDE 的“帮助目录”(F1)中的 About Structuring Web Source Files(关于结构化 Web 资源文件)。

 

准备网页

该应用程序的表示层包含两个 JSP 页面:欢迎页面(welcome page)和向用户返回指定数据的响应页面(response page)。您可以从为这两个页面创建占位符开始。也就是说,您将要现在添加 HTML,并在逻辑层实现后再添加特定于 JSP 的代码。

实现欢迎页面


index.jsp 转换为 IFPWAFCAD 的欢迎页面:

  1. 确保 index.jsp 在 Source Editor 中打开。如果还未打开,在 Projects 窗口的 IFPWAFCAD > Web Pages 中双击 index.jsp。然后,在 Source Editor 中,将标题更改为 IFPWAFCAD Homepage。
  2. 将主体中列出的内容用以下代码代替:
    <body>
    <br>
    <h2 align="center">Welcome to IFPWAFCAD, the International Former Professional
    <br>Wrestlers' Association for Counseling and Development!</h2>
    
    <br><br>
    <table width="55%" align="center">
    <tr>
    <td><strong>IFPWAFCAD offers expert counseling in a wide range of fields.</strong></td>
    </tr>
    <tr>
    <td><br>To view the contact details of an IFPWAFCAD certified former
    <br>professional wrestler in your area, select a subject below:</td>
    </tr>
    <tr>
    <td>
    <form action="response.jsp" method="post">
    <br>
    <strong>Select a subject:</strong>
    <select name="subject_id" size="1" >
    <option value="1">Marriage Guidance</option>
    <option value="2">Financial Consultancy</option>
    </select>
    <input type="submit" name="submit" value="submit">
    </form>
    </td>
    </tr>
    </table>
    </body>

    这会创建一个位于表格内部的简单表单。然后,当您实现 JSP 代码后,您将使用一个直接从数据库中抓取所有主题名称的循环代替该示例主题。另外,注意该表单向您将要创建的 response.jsp 页面提交。

实现响应页面


按以下操作为 response.jsp 创建一个占位符:

  1. 在 Projects 窗口中右键单击 IFPWAFCAD 项目节点,并选择 New > JSP。这将打开 New JSP File 对话框。
  2. 在 JSP File Name 字段中,输入 response。注意在 Location 字段中选择 Web Pages,表示该文件将和欢迎页面在同一目录下创建。
  3. 接受所有其他默认设置并单击 Finish 按钮。即生成新 response.jsp 页面模板,并会在 Source Editor 中打开。在 Projects 窗口中的Web Pages 下面会显示一个新的 JSP 节点:

    response.jsp节点显示在Projects窗口中
  4. 在 Source Editor 中,将标题暂时更改为“(Chosen Subject)”之类的标题。
  5. 然后,使用以下代码代替该模板的主体:
    <body>
    <br>
    <h2 align="center">(Chosen Subject)</h2>
    <br>
    <table width="60%" align="center" cellpadding="10">
    <tr>
    <td valign="top" width="25%"><strong>Description:</strong></td>
    <td><em>(subject description)</em><br></td>
    </tr>
    <tr>
    <td valign="top"><strong>Counselor:</strong></td>
    <td><span style="font-size:large"><strong>(counselor's name)</strong></span>
    <br><span style="align:center">
    <em>member since:(a date)</em></span></td>
    </tr>
    <tr>
    <td valign="top"><strong>Contact Details:</strong></td>
    <td><strong>email:</strong><a href="mailto:<(an email address)>"><(an email address)></a>
    <br><strong>phone:</strong><(a telephone number)></td>
    </tr>
    </table>
    </body>

    这为输出创建了一个 HTML 模板,您在 JSP 中编码后就会生成输出。注意:以上所有包含在圆括号中的字段将会通过访问数据层动态生成。

 

部署到服务器

为了了解用户看到的应用程序将会是什么样子,将您目前已经构建的内容部署到 Web 服务器,以便在浏览器中查看该页面。注意:该 JSP 页面目前还不包含任何 JSP 代码,所以现在您可以简单地将其扩展名更改为 .htm 并在浏览器中单独打开它们。但是,您将需要 Web 服务器来编译逻辑层的 JSP 代码以及 Java 类,所以您也需要开始使用 Web 服务器。

无论您使用 NetBeans IDE 绑定的 Tomcat 或 SJSAS,一旦您在 IDE 中注册了服务器,部署应用程序的过程都是一样的。如果您需要对 IDE 中的服务器设置进行任何更改,请从主菜单中选择 Tools > Server 来打开 Server Manager。

将应用程序部署到服务器:

  1. 在 Projects 窗口中,右键单击该项目节点并选 择Deploy Project。NetBeans IDE 会自动启动服务器(如果它还未启动),对其进行编译,然后将该项目部署到服务器。您可以在 Output 窗口中看到所有生成的输出。该输出应以消息 BUILD SUCCESSFUL 结束。

    要检查该应用程序已确实部署到服务器,请打开 Runtime 窗口(Ctrl+5)并展开 Servers 节点。在 IDE 中注册的服务器在此处列出。如果是 Tomcat,请展开 Web Applications 以查看在服务器上编译的 IPFWAPCAD 应用程序。如果是 SJSAS,请展开 Applications > Web Applications 来查看该应用程序。
  2. 要运行该项目,请返回 Projects 窗口,并从项目节点的右键菜单中选择 Run Project。则 index.jsp 页面在 IDE 的默认浏览器中打开。

    提示:如果您已经首先选择 Run Project,则该应用程序会在浏览器中打开之前自动被编译并被部署到服务器。

 

实现数据层

在中间的逻辑层进行编码之前,准备好数据层。该步骤可划分为几个子任务:

  1. 在 NetBeans IDE 中准备数据库
  2. 设置 JDBC 连接池
  3. 通过应用程序引用 JDBC 源
  4. 将数据库驱动程序的 JAR 文件添加到服务器

在 NetBeans IDE 中准备数据库

完成 连接 MySQL 数据库 这篇教程后,您将会拥有一个到 MySQL 数据库(已在 IDE 中注册)的连接。您也应该有两个表:Counselor Subject,包含从 ifpwafcad.sql 生成的示例数据。

设置 JDBC 连接池

为了指定 Web 服务器允许应用程序与数据库通信的方式,我们需要设置一个数据库连接池。数据库连接池本质上是一组服务器为特定数据库维护的可重复使用的连接。请求到数据库的连接的 Web 应用程序从连接池中获得连接。当应用程序关闭连接后,该连接则返回到连接池。

为了在服务器上创建一个连接,必须首先创建一个 JDBC 源 (也称为数据源)。JDBC 源为应用程序提供到数据库的连接。根据您是使用 Tomcat 还是 SJSAS,执行以下操作:

绑定的 Tomcat Web 服务器

  1. 展开 Servers > Bundled Tomcat > Web Applications 节点(如果有必要,可通过从服务器节点的右键菜单中选择 Start 来首先启动服务器),访问 Runtime 窗口中的 Tomcat Administration 工具。然后右键单击 /admin 节点,并选择 Open in Browser。登陆页面在 IDE 的默认浏览器中打开。
  2. 输入已指定为“admin”角色的一个用户的用户名和密码。如果您需要验证此信息,请检查 conf 文件夹(位于服务器的基目录中)中的 tomcat-users.xml 文件。您可以通过打开 Server Manager (Tools > Server Manager)、从左侧窗格中选择 Tomcat 并查看 Connection 选项卡下的 Catalina Base 字段的条目找到基目录:

    Tomcat base directory shown in the Server Manager
  3. 登陆后,从左栏中选择 Resources > Data Sources。在显示的主窗口中,从 Data Source Actions 下拉菜单中选择 Create New Data Source。在对应的字段中输入以下值:

    • JNDI Name:jdbc/connectionPool
    • Data Source URL:jdbc:mysql://localhost:3306/MyNewDatabase
    • JDBC Driver Class:com.mysql.jdbc.Driver
    • User Name:root
    • Password:nbuser

    要更好地理解这个过程,请参阅IDE的“帮助目录”(F1)中的 About Connection Pools(关于连接池)主题。

    当您确定您输入的值与下面的屏幕截图中的内容相匹配时,请单击 Save。然后单击 Commit Changes,并 Log Out。

    Tomcat's Admin interface for creating a new data source

Sun Java System Application Server


在 SJSAS 上建立 JDBC 连接池要稍微容易一些,因为可以完全在 NetBeans IDE 内建立:

  1. 在 Projects 窗口中,右键单击项目节点并选择 New > File/Folder.... 在 Categories 下选择 Sun Resources;在 File Types 下选择 JDBC Resource。单击 Next 按钮。
  2. 在 General Attributes 窗格中,选择 Create New JDBC Connection Pool 选项,然后在下面的 JNDI Name 中输入 jdbc/connectionPool。其余设置保持默认并单击 Next。在 Additional Properties 窗格中继续单击 Next。
  3. 在Choose Database Connection 窗格中,注意:连接池名称自动根据以上指定的 JNDI 名称自动提供。确保 Extract from Existing Connection 选项被选中,并从下拉列表中选择您使用的数据库连接 (jdbc:mysql://localhost:3306/MyNewDatabase)。单击 Next 按钮。
  4. 在 Add Connection Pool Properties 窗格中,所有设置保持默认值,并单击 Finish。则在项目中创建了新的数据源和连接池。您可以通过展开 Server Resources 节点查看刚创建的数据源和连接池来进行验证:

    Projects窗口中的数据源和连接池

尽管您刚在项目中创建了一个数据源和连接池,仍然必须向应用程序服务器注册它们:请执行以下操作:

  1. 从数据源和连接池节点的右键菜单中选择 Register。在显示的 JDBC Resource Registration 对话框中,单击 Register,然后单击 Close。
  2. 为了验证确实已经在服务器上创建了 JDBC 源和连接池,您可以切换到 Runtime 窗口,并从 Sun Java System Application Server 节点的右键菜单中选择 View Admin Console。管理登陆页面在 IDE 的默认浏览器中打开。
  3. 登陆到控制台(默认情况下,用户名和密码为:adminadminadmin)。从左栏中选择 Resources,然后在主窗口中单击 JDBC。
  4. 现在,当您浏览 JDBC Resources 和 Connection Pools 页面时,您应该看到新创建的数据源(jdbc/connectionPool)和连接池(connectionPool)。

从应用程序引用 JDBC 源

现在您需要从 Web 应用程序中引用您创建的 JDBC 源。这意味着您既需要访问 Web 应用程序的一般部署描述符(web.xml),又需要访问您正在使用的服务器的特定于服务器的部署描述符(对于 Tomcat 为 context.xml;对于 SJSAS 为 sun-web.xml)。

部署描述符为 XML 文档,包含描述应该如何部署应用程序的信息。例如,它们通常用于指定 servlet 和 JSP 文件的位置和可选参数,以及应用程序的实现基本安全功能。有关相信信息,请参阅 IDE 的“帮助目录”(F1)中的Configuring Web Application Deployment Descriptors(配置Web应用程序部署描述符)主题。

要引用一般部署描述符中的 JDBC 源:

  1. 在 Projects 窗口中,展开 Web Pages > WEB-INF 子文件夹,并双击 web.xml。会为该文件在 Source Editor 中显示一个图形化的编辑器。
  2. 单击位于 Source Editor 顶部的 References 选项卡。展开 Resource References 题头,然后单击 Add... 打开 Add Resource Reference。
  3. 在 Resource Name 中,输入当您将数据源添加到上面的服务器(jdbc/connectionPool)时给定的 JNDI 名称。在 Description 中,输入数据源 URL (jdbc:mysql://localhost:3306/MyNewDatabase)。其他字段保持默认,并单击 OK。新源被添加到 Resource References 题头下:

    new JDBC resource listed in the deployment descriptor

    要验证该源现在已添加到 web.xml 文件,请单击位于 Source Editor 顶部的 XML 选项卡,您将会看到包含以下 <resource-ref> 标记:
    <resource-ref>
    <description>jdbc:mysql://localhost:3306/MyNewDatabase [root on Default schema]</description>
    <res-ref-name>jdbc/connectionPool</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

根据您是使用 Tomcat 还是 SJSAS,执行以下步骤来引用在特定于服务器的部署描述符中的 JDBC 源。

绑定的Tomcat Web服务器

  1. 在 Projects 窗口中,展开 Web Pages > META-INF 子文件夹,并双击 context.xml。该文件将在 Source Editor 中显示。
  2. 添加以下 <ResourceLink> 标记,然后保存文件(用粗体表示更改):
    <?xml version="1.0" encoding="UTF-8"?>
    <Context path="/IFPWAFCAD">
    <ResourceLink global="jdbc/connectionPool" name="jdbc/connectionPool" type="javax.sql.DataSource"/>
    </Context>

Sun Java System Application Server

  1. 在 Projects 窗口中,展开 Web Pages > WEB-INF 子文件夹,并双击 sun-web.xml。会为该文件在 Source Editor 中显示一个图形化的编辑器。
  2. 单击编辑器右上角的 Edit As XML。该文件以 XML 格式显示。在文档中输入以下 <resource-ref> 标记,例如:在关闭 </jsp-config> 标记后面:
    <resource-ref>
    <res-ref-name>jdbc/connectionPool</res-ref-name>
    <jndi-name>jdbc/connectionPool</jndi-name>
    </resource-ref>

将数据库驱动程序的 JAR 文件添加到服务器

添加数据库驱动程序的 JAR 文件也是另一个使服务器能够与数据库通信的关键步骤。您需要找到您的数据库驱动程序的安装目录。如果您从 连接 MySQL 数据库 教程程开始,则您使用安装到计算机的 C:\MySQL Connector/J。复制驱动程序根目录中的 mysql-connector-java-5.0.5-bin.jar 文件,然后根据您使用 Tomcat 或 SJSAS,执行以下操作:

绑定的 Tomcat Web 服务器

  • 将 JAR 文件粘贴到 Tomcat 的 common/lib 子文件夹。默认情况下,服务器在 IDE 安装目录的 enterprise 子文件夹下。如果您已经启动了服务器,请确保在粘贴了 JAR 文件后启动它,这样服务器可以加载该文件。

Sun Java System Application Server

  • 找到 SJSAS 的安装目录,然后将 JAR 文件粘贴到服务器的 domains > domain1 > lib > ext 子文件夹。例如,如果您将服务器安装到 C:\,则路径为:C:\Sun\AppServer\domains\domain1\lib\ext。当您连接到 NetBeans IDE 中的 SJSAS,则您实际上连接到了该应用程序服务器的一个实例。每个实例在单独的域中运行应用程序,所以我们需要将 JAR 文件放置在 domain1 中,这是安装 SJSAS 时创建的默认域。如果您已经启动了服务器,请确保在粘贴了 JAR 文件后启动它,这样服务器可以加载该文件。

 

实现逻辑层

由于已经准备好了数据层,可以开始使 Java 类就位了。如 上图 所示,逻辑层包含三个类:SubjectName.javaSubjectCounselor.javaAccessDB.java。这些类提供两个功能:它们通过响应数据请求与 JSP 页面连接(SubjectName.javaSubjectCounselor.java),并且它们通过根据用户指定的信息与数据库连接(AccessDB.java)。您可以根据这两个功能继续进行:

  1. 连接 JSP 页面
  2. 连接数据库

连接 JSP 页面

SubjectName.java

SubjectName.java 使 index.jsp 页面可以按 Subject 表中列出的访问标题名称。方法是,通过允许 AccessDB.java 使用 setter 方法设置实例变量 id name,然后让 index.jsp 使用公共的 getter 方法访问它们。要设置 SubjectName.java,请执行以下操作:

  1. 在 Projects 窗口中,右键单击项目节点并选择 New > Java Class。则打开 New Java Class 向导。
  2. 在 Class Name 文本字段中输入 SubjectName。您也应该创建一个新的包,以包含该项目所有的 Java 类。在 Package 中,键入 org。单击 Finish 按钮。即在 Source Editor 打开新类的一个模板。在 Projects 窗口中,该新包的节点和 Source Packages 中显示的类:

    Projects窗口中显示的新org包和SubjectName节点。
  3. 现在,在 Source Editor 中新创建的模板中,将以下内容添加到新的 SubjectName 类的主体中,然后保存(Ctrl+S)该文件:
    private String id;
    private String name;
    
    // create setter methods
    public void setId(String id){
    this.id = id;
    }
    
    public void setName(String name){
    this.name = name;
    }
    
    // create getter methods
    public String getId(){
    return id;
    }
    
    public String getName(){
    return name;
    }

SubjectCounselor.java

SubjectCounselor.java 使 response.jsp 页面可以根据从 index.jsp 中的表单接收到的 subject_id 值,从数据库访问主题和参考信息。像 SubjectName.java 一样,该类通过允许 AccessDB.java 使用公共的 setter 方法设置所有的实例变量,然后让 response.jsp 使用 getter 方法访问它们。要设置 SubjectCounselor.java,请执行以下操作:

  1. 在 Projects 窗口中,右键单击项目节点并选择 New > Java Class。则打开 New Java Class 向导。
  2. 在 Class Name 文本字段中输入 SubjectCounselor。单击 Finish 按钮。即在 Source Editor 打开新类的一个模板。在 Projects 窗口中,在我们以前创建的 org 包下显示一个新类节点。
  3. 现在,在 Source Editor 中新创建的模板中,将以下内容添加到新的 SubjectCounselor 类的主体中,然后保存(Ctrl+S)该文件:
    private String subjectName;
    private String description;
    private String counselorID;
    private String firstName;
    private String nickName;
    private String lastName;
    private String telephone;
    private String email;
    private String memberSince;
    
    // create setter methods
    public void setSubjectName(String subject) {
    this.subjectName = subject;
    }
    
    public void setDescription(String desc) {
    this.description = desc;
    }
    
    public void setCounselorID(String counsId) {
    this.counselorID = counsId;
    }
    
    public void setFirstName(String first) {
    this.firstName = first;
    }
    
    public void setNickName(String nick) {
    this.nickName = nick;
    }
    
    public void setLastName(String last) {
    this.lastName = last;
    }
    
    public void setTelephone(String phone) {
    this.telephone = phone;
    }
    
    public void setEmail(String email) {
    this.email = email;
    }
    
    public void setMemberSince(String mem){
    this.memberSince = mem;
    }
    
    // create getter methods
    public String getSubjectName() {
    return subjectName;
    }
    
    public String getDescription() {
    return description;
    }
    
    public String getCounselorName() {
    String counselorName = firstName + " "
    + nickName  + " " + lastName;
    return counselorName;
    }
    
    public String getMemberSinceDate() {
    return memberSince;
    }
    
    public String getTelephone() {
    return telephone;
    }
    
    public String getEmail() {
    return email;
    }

连接数据库

AccessDB.java

您可以通过集中于其单个任务来编码 AccessDB.java:它必须连接到数据库,发送用户指定的请求,然后存储从查询接收到的数据。由于您以分步的方式来编码 AccessDB.java,您可以在 这里 下载一个 AccessDB.java 的有效版本。这样,如果您在任何点丢失了内容,你可以和已保存的版本比较您的代码。

开始,创建文件并准备使该类建立到我们以上定义的连接池的连接的代码:

  1. 在 Projects 窗口中,右键单击项目节点并选择 New > Java Class。则打开 New Java Class 向导。
  2. 在 Class Name 文本字段中输入 AccessDB。单击 Finish 按钮。即在 Source Editor 打开新类的一个模板。在 Projects 窗口中,在我们以前创建的 org 包下显示一个新类节点。
  3. 在 Source Editor 中新创建的模板中,右键单击 canvas 并选择 Enterprise Resources > Use Database。在 Choose Database 对话框中,从 Data Source 下拉列表中选择我们以前定义的数据源(jdbc/connectionPool)的 JNDI 名称。确保已选中 Generate Inline Lookup Code 选项并单击 Finish。在 Source Editor 中生成以下代码:
    private DataSource getJdbcConnectionPool() throws NamingException {
    Context c=new InitialContext();
    return (DataSource) c.lookup("java:comp/env/jdbc/connectionPool");
    }
    这允许该类使用我们先前在 Web 服务器上定义的连接池连接到数据库。同时注意:创建 getJdbcConnectionPool()方法时,IDE 在Source Editor 中自动为 javax.sqljavax.naming API 的以下类生成导入语句:

    在Source Editor中显示的导入语句

现在您可以编码该类为两个 JSP 页面执行的数据库查询。首先编码 index.jsp 的查询,该查询涉及检索 Subject 表中列出的所有主题的名称和 ID。

  1. AccessDB.java 的 Source Editor 中,在类声明下面输入以下字符串变量:
    private String sqlSubjectName = "SELECT subject_id, name FROM Subject";

    SQL 查询允许您指定想要从数据库中拉出的数据。
  2. 将以下 getSubjectName() 方法添加到类。此步骤创建了一个到连接池的连接,然后连接到数据库并执行查询。然后它会环绕从数据库返回的结果集,并创建一个 SubjectName 的实例,以保留每个返回行的ID和名称。每个实例添加到一个列表,该列表最后被返回到调用该方法的对象:
    // get subject names from database
    public List getSubjectName() throws Exception{
    
    // connection instance
    Connection connection = null;
    
    // instance of SubjectName used to retain retrieved data
    SubjectName subName = null;
    
    // list to hold all instances of SubjectName
    List list = new ArrayList();
    
    try {
    // connect to database
    DataSource dataSource = getJdbcConnectionPool();
    connection = dataSource.getConnection();
    
    // prepare the SQL query to get subject name and id
    PreparedStatement ps = connection.prepareStatement(sqlSubjectName);
    
    // set up the result set to retain all queried data
    ResultSet rs = ps.executeQuery();
    
    // now loop through the rows from the generated result set
    while(rs.next()){
    // declare an instance of SubjectName to match
    // returned data with class' instance variables
    subName = new SubjectName();
    String subject_id = rs.getString("subject_id");
    String name = rs.getString("name");
    // set the data to the variables
    subName.setId(subject_id);
    subName.setName(name);
    // finally, add the subName instance to the list
    list.add(subName);
            }
    
    } catch(Exception e){
    System.out.println(e.getMessage());
    
    // close the connection so it can be returned to
    // the connection pool then return the list
    } finally{
    connection.close();
    return list;
        }
    }
    getSubjectName() 方法添加以上代码后,注意在 Source Editor 中出现的各种错误,文本下面标有红线。当您将光标放置在有下划线的文本上时,在下划线的最左侧将会显示一个灯泡图标。这表示 IDE 可以为该错误提供一个可行的解决方案。
  3. 通过单击灯泡图标或者按下 Alt-Enter 打开相应的工具提示更正所有错误:

    Source Editor中显示的工具提示

    有 5 个错误您是需要关心的,并且它们都涉及导入类(以及接口)到项目中:

    • 用作该方法的返回对象的 List 接口需要 java.util 中的定义。
    • 采用了 ArrayList 实现 List,您需要此类以保存 SubjectName 的所有实例。
    • 要求 java.sql API 中的 ConnectionPreparedStatement ResultSet,以便和数据库通信。

    选择每个的工具提示中选择 Add Import,并注意在 Source Editor 中生成了新的导入语句:

    在Source Editor中显示的导入语句

现在您可以为 response.jsp 中的查询添加代码。这遵循和以上对 index.jsp 展示的一样的模式,例如,您创建一个合适的 SQL 查询,然后创建一个方法来查询数据库并保存数据。但是在这种情况下,您需要创建两个查询:第一个访问 Subject 表并检索与用户从 index.jsp 中的下拉菜单中选择的 ID 对应的行。然后第二个查询使用返回的主题行中的 counselor_idfk 匹配 Counselor 表中的咨询 ID,继续此过程。

  1. AccessDB.java 的 Source Editor 中,在类声明下面输入以下两个字符串变量:
    private String sqlSubject = "SELECT * FROM Subject WHERE subject_id = ?";
    private String sqlCounselor = "SELECT * FROM Counselor WHERE counselor_id = ?";
  2. 将以下 getSubCounselor() 方法添加到类。此步骤创建了一个到连接池的连接,然后连接到数据库并执行两个查询(如上所述)。然后创建一个 SubjectCounselor 的实例,以保存从两个结果集中获得的所有数据:
    // get subject data and counselor data for corresponding subject
    public SubjectCounselor getSubCounselor(String subjectID) throws Exception{
    
    // instance of SubjectCounselor used to retain data
    SubjectCounselor subCoun = new SubjectCounselor();
    
    // connection instance
    Connection connection = null;
    
    try {
    // connect to database
    DataSource dataSource = getJdbcConnectionPool();
    connection = dataSource.getConnection();
    
    // prepare the SQL query to get subject data
    PreparedStatement ps = connection.prepareStatement(sqlSubject);
    ps.setString(1, subjectID);
    ResultSet rs = ps.executeQuery();
    // this assumes there is only one row in the result set
    rs.next();
    // match all returned fields with the below variables
    String subjectName = rs.getString("name");
    String description = rs.getString("description");
    String counselorID = rs.getString("counselor_idfk");
    
    // prepare the SQL query to get counselor data
    ps = connection.prepareStatement(sqlCounselor);
    ps.setString(1, counselorID);
    rs = ps.executeQuery();
    // this assumes there is only one row in the result set
    rs.next();
    // match all returned fields with the below variables
    String firstName = rs.getString("first_name");
    String nickName = rs.getString("nick_name");
    String lastName = rs.getString("last_name");
    String telephone = rs.getString("telephone");
    String email = rs.getString("email");
    String memberSince = rs.getString("member_since");
    
    // finally set all variables to their
    // equivalents in the SubjectCounselor instance
    subCoun.setSubjectName(subjectName);
    subCoun.setDescription(description);
    subCoun.setCounselorID(counselorID);
    subCoun.setFirstName(firstName);
    subCoun.setNickName(nickName);
    subCoun.setLastName(lastName);
    subCoun.setTelephone(telephone);
    subCoun.setEmail(email);
    subCoun.setMemberSince(memberSince);
    } catch(Exception e){
    System.out.println(e.getMessage());
    } finally{
    // close the connection so it can be returned to the
    // connection pool then return the SubjectCounselor instance
    connection.close();
    return subCoun;
        }
    }

您现在已经完成了 AccessDB.java 所需的代码,以及实现逻辑层所需的所有必须步骤。您可能想要在继续之前与 可下载的版本 比较您的 AccessDB.java 版本。余下的唯一任务就是将 JSP 代码添加到您的 Web 页面,允许您显示在 SubjectName SubjectCounselor 的实例中维护的数据。

 

实现表示层

如果您返回在本教程中先前创建的 index.jsp response.jsp 占位符,您可以添加 JSP 代码以使页面可以动态生成内容,例如:根据用户输入生成。要添加 JSP 代码,您需要执行以下三个步骤:

  1. 在项目的编译类路径中添加 JSTL 库
  2. 在 JSP 页面中添加 taglib 指令
  3. 添加代码

在项目的编译类路径中添加 JSTL 库

为了更好根据我们的配置利用 JSP 资源,您使用 JavaServer Pages Standard Tag Library (JSTL)中的标记来访问和显示从逻辑层中获得的数据。该库是和 IDE 绑定的。因此您需要确保将 JSTL 库添加到该 Web 项目的编辑类路径中,然后添加相关的 taglib 指令到每个 JSP 页面。这允许我们使用的服务器在它从 JSP 页面读取标记时能够识别这些标记。根据您是使用 Tomcat 还是 SJSAS,执行以下操作:

绑定的 Tomcat Web 服务器

  1. 在 Projects 窗口中,右键单击项目的 Libraries 节点并选择 Add Library。选择 JSTL 1.1 库,并单击 Add Library。
  2. 现在展开 Libraries 节点,您将会看到两个新节点:一个用于 JSTL 库的 standard.jar 文件,另一个用户该库的 jstl.jar 文件:

    JSTL library added to Libraries node in Projects window

Sun Java System Application Server

如果您使用的是 Sun Java System Application Server,您不需要执行任何操作来添加 JSTL 库到该项目的编译类路径。这是因为JSTL库已经包含在编辑服务器的库中了。您可以通过展开 Libraries > Sun Java System Application Server 节点来验证。appserv-jstl.jar 节点定义所有 JSTL 库中的标准标记。

在 JSP 页面中添加 taglib 指令

无论您使用什么服务器,您都需要将必需的 taglib 指令添加到 JSP 页面:

  1. 在 Source Editor 中打开 index.jspresponse.jsp。将以下指令添加到两个页面:
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    注意:创建这些页面后,该指令就被自动生成,作为JSP模板中的注释。您可以通过删除 <%-- --%> 标记取消对该指令的注释:

    JSTL library added to Libraries node in Projects window

添加代码

最后,将代码添加到每个页面。您需要访问 SubjectName(对于index.jsp)和 SubjectCounselor 实例(针对 response.jsp)的列表,然后使用 HTML 显示这些数据。

index.jsp

  1. 将以下代码添加到文件顶部的某个地方,例如就在 HTML doctype 声明的上面:
    <%-- create an instance of AccessDB --%>
    <% AccessDB accessDB = new AccessDB(); %>
    
    <%-- create an instance of List, then retrieve SubjectNames --%>
    <% List subjNames = accessDB.getSubjectName(); %>
    
    <%-- make list accessible to page --%>
    <% request.setAttribute("subjNames", subjNames); %>

    您声明并设置一个 List 变量,以包含 SubjectName(从调用 AccessDB getSubjectName() 方法返回)的列表。然后应用 setAttribute() 方法到 subjNames 变量,这样发出请求的页面对其可访问(如下面当您插入一个循环到 HTML 表单中以提取 subName 的内容所示)。
  2. 添加以下 JSP 导入语句到页面:
    <%@ page import="org.*" %>
    <%@ page import="java.util.List" %>

    第一个导入允许该页面访问您在项目中创建的 org 包中包含的所有类。第二个定义用于您声明的变量的 List 类。
  3. 在 HTML 表单中,在 <select> 标记之间,使用以下代码代替 <option> 标记(更改以粗体表示):
    <select name="subject_id" size="1" >
    <c:forEach var="subName" items="${requestScope.subjNames}" >
    <option value="${subName.id}">${subName.name}</option>
    </c:forEach>
    </select>

    这里是循环。 TheforEach 标记从 subName 中提取所有值并提取每个主题的名称和 ID,使用这些填充表单的下拉列表。

    也请注意 forEach 前的 c: 前缀。这引用了 JSTL core 库(您在 上面 为其添加了一个 taglib 指令)。
  4. 保存更改(Ctrl+S),然后重新将项目部署到服务器,并尝试再次运行(F6)。这一次,当 index.jsp 在浏览器中显示时,该主题下拉列表应该包含从数据库检索的主题名称:

    subject drop-down list displayed in a browser window

response.jsp

  1. 将以下代码添加到文件顶部的某个地方,例如就在 HTML doctype 声明的上面:
    <%-- get the value from the form --%>
    <% String subjectID = request.getParameter("subject_id"); %>
    
    <%-- create an instance of AccessDB --%>
    <% AccessDB accessDB = new AccessDB(); %>
    
    <%-- create an instance of SubjectCounselor using form value --%>
    <% SubjectCounselor subCoun = accessDB.getSubCounselor(subjectID); %>
    
    <%-- create variables to hold data from SubjectCounselor --%>
    <% String name = subCoun.getSubjectName(); %>
    <% String description = subCoun.getDescription(); %>
    <% String counselor = subCoun.getCounselorName(); %>
    <% String memberSince = subCoun.getMemberSinceDate(); %>
    <% String telephone = subCoun.getTelephone(); %>
    <% String email = subCoun.getEmail(); %>

    这里您创建一个字符串变量来保存 subject_id,从 index.jsp 中的表单发送的值。然后,您为 SubjectCounselor 声明并设置一个变量,以保存从调用 AccessDB getSubCounselor() 方法返回的数据。最后,您声明并设置一组字符串变量,以保存在 SubjectCounselor 实例中保存的数据。您将直接从页面的 HTML 中访问这些字符串变量。
  2. 添加以下 JSP 导入语句到页面:
    <%@ page import="org.*" %>

    对于上面的 index.jsp,您必须允许页面访问在项目的 org 包中包含的所有类。
  3. 现在,在 HTML 中,使用以下 JSP 调用代替以前在括号中包含的文本,以显示变量。更改以粗体显示:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><%= name %></title>
    </head>
    <body>
    <br>
    <h2 align="center"><%= name %></h2>
    <br>
    <table width="60%" align="center" cellpadding="10">
    <tr>
    <td valign="top" width="25%"><strong>Description:</strong></td>
    <td><em><%= description %></em><br></td>
    </tr>
    <tr>
    <td valign="top"><strong>Counselor:</strong></td>
    <td><span style="font-size:large"><strong><%= counselor %></strong></span>
    <br><span style="align:center">
    <em>member since:<%= memberSince %></em></span></td>
    </tr>
    <tr>
    <td valign="top"><strong>Contact Details:</strong></td>
    <td><strong>email:</strong><a href="mailto:<%= email %>"><%= email %></a>
    <br><strong>phone:</strong><%= telephone %></td>
    </tr>
    </table>
    </body>
    </html>

    在将此页面返回到客户端浏览器之前,服务器会将 JSP 变量的所有值直接插入到 HTML。因此现在您可以直接从响应页面的数据层访问数据。
  4. 最后,保存更改(Ctrl+S),然后重新将项目部署到服务器,并尝试再次运行(F6)。当 index.jsp 在浏览器中显示时,从下拉列表中选择一个主题。 并单击 Submit。现在您应该前进到 response.jsp 页面,显示与您的选择对应的详细信息:

 

未来计划

“使用 MySQL 在 NetBeans IDE 中创建一个简单的 Web 应用程序”教程到此结束。本教程展示了如何创建一个连接到 MySQL 数据库的简单的分布式 Web 应用程序。也展示了如何使用基本的三层架构构建应用程序,并使用 JSP 向客户端浏览器显示后端数据。

尽管构建应用程序本身看起来需要大量工作,而只有如此小的结果,但是您现在有了一个分布式的框架,意味着您现在可以方便地维护应用程序数据,以及修改或将应用程序扩展到更大规模。

有关相关教程或更高级的教程,请参阅以下资源: