赞
踩
源自:http://blog.csdn.net/java060515/archive/2007/06/19/1658316.aspx)
在NetBeans中使用MySQL创建简单Web应用程序(一)
本文介绍了如何创建与 MySQL 数据库连接的简单、分布式 Web 应用程序。此外,本文还涉及 Web 开发的一些基本想法和技术,如 Java Server Pages 和三层架构,我们会在构造 Web 应用程序时详细介绍。本教程专为基本了解 Java 编程和 Web 开发,并渴望实践所学知识的初学者设计。
作为一种流行的开放源数据库管理系统,MySQL凭借其速度、灵活性和可靠性方面的优势普遍用于 Web 应用程序中。MySQL 采用 SQL 或 Structured Query 语言,访问并处理数据库中包含的数据。
本教程是 Connecting to a MySQL Database 教程的继续。本教程假设您已在NetBeans IDE 中创建并配置了到 MySQL 数据库的连接。您还需要 ifpwafcad.sql 中包括的数据库表数据。该 SQL 文件创建了两个表,counselors 和 subjects,然后使用样例数据填充它们。将该文件保存到本地目录中,然后在 NetBeans 中打开它并在您的 MySQL 数据库中运行它。在本文中,我们工作的数据库命名为 test。
预计持续时间:40分钟
本教程将介绍以下主题:
l 获得软件
l 规划结构
l 创建一个新项目
l 部署到服务器
l 实现数据层
l 实现逻辑层
l 实现演示层
l 下一步
开始之前,确保您在计算机上安装了如下软件:
l NetBeans IDE 5.5
l Java SE Development Kit (JDK™) version 5.0 或更高版本
l MySQL 数据库
l JDBC Driver for MySQL
l Sun Java System Application Server
注意:本教程中未严格要求使用 Sun Java System Application Server (SJSAS),因为您可以使用 Tomcat, 它是与 NetBeans IDE 绑定的 Web 服务器。然而,如果您计划在 IDE 中开发应用程序,那么应用程序服务器会提供很多工具和技术支持,使开发人员的工作更轻松。
简单的 Web 应用程序通常采用三层架构设计,其中的用户界面、功能流程逻辑和数据访问与存储均可独立地进行维护。换句话说,这三层的每一层代表了可在自己平台上运行的模块(因此使用术语“分布式”)。
对于本教程中构建的应用程序而言,演示层或用户界面由 JSP 页面表示,这些页面用来准备发送给客户端浏览器的 HTML。我们可以使用几个简单的 Java 类来编码中间层或逻辑层。最后,可以使用 MySQL 数据库中的几个表实现数据层。考虑以下的客户端服务器场景:
浏览器中显示的欢迎页面 (index.jsp) 包含一个简单窗体,允许访问者指定数据。当一个请求传递到包含数据的服务器时,开始访问 JSP 页面(response.jsp),该页面可立即将指定数据传递给 SubjectCounselor.java,这样信息检索流程可以开始了。Java 类处理数据并利用 AccessDB.java 准备发送给数据库的 SQL 查询。然后,AccessDB.java 与数据库连接,按照 SQL 查询指定的内容,从 subjects 和 counselors 表中检索数据。最后,启动返回行程,response.jsp 中包含的检索到的数据形成了服务器对客户端的响应。
为了实现上述场景,我们为名为 IFPWAFCAD 的虚拟组织或者国际前职业摔跤手咨询与发展联盟开发一个简单的应用程序。利用该应用程序,用户可以从下拉列表 (index.jsp) 中选择咨询主题,然后从 MySQL 数据库中检索数据并将信息返回给用户 (response.jsp):
让我们首先在 IDE 中创建一个新项目:
应用程序的演示层包括两个 JSP 页面:欢迎页面和将指定数据返回给用户的响应页面。我们可以首先为这两个页面创建占位符。这意味着,现在将添加 HTML,然后一旦实现了逻辑层就添加特定于 JSP 的代码。
让我们首先将 index.jsp 转换到 IFPWAFCAD 的欢迎页面:
<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 的占位符,执行以下操作:
<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>
一旦我们在 JSP 中编码,就会为将要生成的输出创建一个 HTML 模板。注意,上面所有括号中的字段都可以通过访问数据层动态生成。
要了解应用程序在用户那看起来是怎样的,我们需要部署目前所得到的应用程序到 Web 服务器,以便在浏览器上看到页面。注意我们的 JSP 页面尚未包含任何 JSP 代码,因此您现在可以简单地更改扩展名为 .htm,然后在浏览器中单独打开它们。然而,我们需要 Web 服务器编译 JSP 代码以及逻辑层的 Java 类,因此也可能开始使用 Web 服务器。
无论您正在运行 NetBeans IDE 捆绑的 Tomcat 还是 SJSAS,一旦在 IDE 中注册了服务器,部署应用程序的过程是相同的。如果需要对 IDE 中的服务器设置进行任何更改,请从主菜单中选择 Tools > Server Manager 打开 Server Manager。
要部署应用程序到服务器:
在考虑为中间逻辑层编码之前,先准备好数据层。这可以容易地分成几个简单的子任务:
2. 设置 JDBC 连接池
完成与 MySQL 数据库连接 教程之后,您将已经拥有一个与 IDE 中注册的 MySQL 数据库的连接。应该还有两个表, counselors 和 subjects,包含 ifpwafcad.sql 中生成的样例数据。
为了指定 Web 服务器允许的应用程序与数据库通信的方式,我们需要设置一个数据库连接池。数据库连接池基本上就是一组可重用连接,服务器使用它维护特定数据库。请求与服务器连接的 Web 应用程序从该池中获得连接。当应用程序关闭连接时,连接返回池中。
为了在服务器上设置连接池,我们需要创建一个 JDBC 资源(也称数据资源)。JDBC 资源为应用程序提供到数据库的连接。根据您使用的是 Tomcat 还是 SJSAS,执行以下操作:
m JNDI Name: jdbc/connectionPool
m Data Source URL: jdbc:mysql://localhost:3306/test
m JDBC Driver Class: com.mysql.jdbc.Driver
m User Name: root
m Password: nbuser
要更好的了解此处执行的操作,请参见 IDE 的 Help Contents (F1) 中的 About Connection Pools。
确定您输入的值与下面屏幕截图中的值一致后,单击 Save。然后单击 Commit Changes,最后单击 Log Out。
在 SJSAS 上设置 JDBC 连接池略微容易一些,因为可以完全在 NetBeans IDE 中完成该设置:
虽然我们刚在项目中创建了数据源和连接池,但仍需要使用应用程序服务器注册它们。执行以下操作:
我们现在需要从 Web 应用程序中引用刚创建的 JDBC 资源。这意味着必须访问 Web 应用程序的通用部署描述符(Web.xml),以及所使用服务器的特定于服务器的部署描述符(Tomcat 的 context.xml;SJSAS 的 sun-Web.xml)。
部署描述符是一种 XML 文档,这些文档包含描述应用程序部署方式的信息。例如,它们通常用于指定 servlets 和 JSP 文件的位置和可选参数,并且为您的应用程序实现基本安全功能。有关更多信息,请参见 IDE 的 Help Contents (F1) 中的 Configuring Web Application Deployment Descriptors。
要引用通用部署描述符中的 JDBC 资源:
<resource-ref>
<description>jdbc:mysql://localhost:3306/test [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 资源:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/IFPWAFCAD">
<ResourceLink global="jdbc/connectionPool" name="jdbc/connectionPool" type="javax.sql.DataSource"/>
</Context>
<resource-ref>
<res-ref-name>jdbc/connectionPool</res-ref-name>
<jndi-name>jdbc/connectionPool</jndi-name>
</resource-ref>
添加数据库驱动的 JAR 文件是实现服务器与数据库通信的不可缺少的另一步。您需要找到数据库驱动的安装目录。如果是继续与MySQL 数据库连接教程的学习,将使用安装到您计算机 C:/ 中的 MySQL Connector/J。在驱动根目录中复制 mysql-connector-java-5.0.5-bin.jar 文件,并根据使用的是 Tomcat 还是 SJSAS 执行以下操作:
l 粘贴 JAR 文件到 Tomcat 的 common/lib 子文件夹中。默认情况下,在 IDE 的安装目录的 enterprise 子文件夹内可以找到服务器。如果已经启动服务器,确保在粘贴了 JAR 文件后重启它,使服务器能够加载它。
l 找到 SJSAS 的安装目录并粘贴 JAR 文件到服务器的 domains > domain1 > lib > ext 子文件夹中。例如,如果将服务器安装到 C:/,则路径为: C:/Sun/AppServer/domains/domain1/lib/ext。在 NetBeans IDE 中与 SJSAS 连接时,您实际是与应用程序服务器的实例连接。每个实例都在一个唯一的域中运行应用程序,因此我们需要在 domain1 中放置 JAR 文件,domain1 是安装 SJSAS 时创建的默认域。如果已经启动服务器,确保在粘贴了 JAR 文件后重启它,使服务器能够加载它。
在NetBeans中使用MySQL创建简单Web应用程序(二)
既然数据层已经准备就绪,我们开始在适当的位置放置 Java 类。逻辑层由三个类组成: SubjectName.java、SubjectCounselor.java 和 AccessDB.java。这几个类提供两种功能;它们通过响应数据请求(SubjectName.java 和 SubjectCounselor.java)连接 JSP 页面,并通过执行基于用户指定信息(AccessDB.java)的查询与数据库进行连接。我们介绍一下这两种功能:
1. 连接 JSP 页面
2. 连接数据库
SubjectName.java 使 index.jsp 页面能够访问 subjects 表中列出的主题名称。它通过允许 AccessDB.java 使用 setter 方法设置实例变量 id 和 name执行此操作,然后让 index.jsp 使用公共 getter 方法访问它们。要设置 SubjectName.java,执行以下操作:
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;
}
根据从 index.jsp 窗体接收到的 subject_id 值,SubjectCounselor.java 能够使 response.jsp 页面访问数据库中的主题和顾问详细信息。像 SubjectName.java 一样,该类通过允许 AccessDB.java 使用公共 setter 方法设置所有实例变量来实现此操作,然后让 response.jsp 使用 getter 方法访问它们。要设置 SubjectCounselor.java,执行以下操作:
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 conId) {
this.counselorID=conId;
}
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;
4. }
我们可以通过将任务各个击破的方式来编码 AccessDB.java:它必须与数据库连接,发送用户指定的查询,然后存储从查询中接收的数据。因为我们以片段的方式处理 AccessDB.java 编码,所以您可以在此下载工作版本的 AccessDB.java。这样,如果在某个点感到迷惑,可以将您的代码与保存的版本进行对比。
首先创建文件,然后准备代码。该代码能使类建立与上面定义的连接池的连接:
private DataSource getJdbcConnectionPool() throws NamingException {
Context c=new InitialContext();
return (DataSource) c.lookup("java:comp/env/jdbc/connectionPool");
}
这允许该类与使用之前在 Web 服务器上定义的连接池的数据库连接。另外,注意在创建 getJdbcConnectionPool() 方法时,IDE 在 Source Editor 中自动生成导入语句,用于 javax.sql 和 javax.naming API 的以下类:
现在可以开始编码该类对两个 JSP 页面执行的数据库查询了。我们首先查询 index.jsp,它涉及检索列在 subjects 表中的所有主题的姓名和 ID:
private String sqlSubjectName="SELECT subjects_id, name FROM subjects";
SQL 查询允许我们指定想要从数据库中引出的数据。
// 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 stat=connection.prepareStatement(sqlSubjectName);
// set up the result set to retain all queried data
ResultSet rs=stat.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("subjects_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 可以为错误提供可能的解决方案。
m 用作方法返回对象的 List 接口需要从 java.util 中定义。
m ArrayList 类被用于实现 List,并且我们需要该类保存 SubjectName 的所有实例。
m 与数据库通信需要来自 java.sql API 的 Connection、PreparedStatement 和 ResultSet。
为这些错误中的每一个从工具提示中选择 Add Import,并且注意在 Source Editor 中自动生成新的导入语句:
现在,可以为来自 response.jsp 的查询添加代码。这与之前演示的 index.jsp 方法相同,例如创建合适的 SQL 查询,然后创建一个查询数据库和保存数据的方法。然而,在这种情况下,需要创建两个查询:第一个访问 subjects 表并检索用户从 index.jsp 的下拉菜单中所选 ID 的相应行。然后通过使用返回的主体行中的 counselors_idfk,第二个查询可以匹配 counselors 表中的 counselor ID:
private String sqlSubject="SELECT * FROM subjects WHERE subjects_id = ?";
private String sqlCounselor="SELECT * FROM counselors WHERE counselors_id = ?";
// get subject data and counselor data for corresponding subject
public SubjectCounselor getSubCounselor(String subjectID) throws Exception{
// instance of SubjectCounselor used to retain data
SubjectCounselor subCon=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 stat=connection.prepareStatement(sqlSubject);
stat.setString(1, subjectID);
ResultSet rs=stat.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("counselors_idfk");
// prepare the SQL query to get counselor data
stat = connection.prepareStatement(sqlCounselor);
stat.setString(1, counselorID);
rs=stat.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
subCon.setSubjectName(subjectName);
subCon.setDescription(description);
subCon.setCounselorID(counselorID);
subCon.setFirstName(firstName);
subCon.setNickName(nickName);
subCon.setLastName(lastName);
subCon.setTelephone(telephone);
subCon.setEmail(email);
subCon.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 subCon;
}
}
现在 AccessDB.java 需要的代码已经添加完成,并且使用它,完成了实现逻辑层所需的所有步骤。可能在继续下一步之前,想要将您的 AccessDB.java 版本与可下载的版本相比较。剩下的唯一任务就是将 JSP 代码添加到 Web 页面中,使我们能够显示在 SubjectName 和 SubjectCounselor 实例中保留的数据。
现在我们返回到之前在本教程中创建的 index.jsp 和 response.jsp 占位符。添加 JSP 代码使我们的页面能动态地生成内容,如基于用户输入生成内容。要实现这个操作,需要采取以下3个步骤:
3. 添加代码
为了能让 JSP 资源更好地为我们所用,我们将使用JavaServer Pages Standard Tag Library (JSTL) 中的标记访问并显示从逻辑层所得的数据。该库与 IDE 捆绑在一起。因此,我们需要确保将 JSTL 库添加到了 Web 项目的编译类路径中,然后向每个 JSP 页面添加相关的 taglib 指令。这样,我们使用的服务器就能够在从 JSP 页面中读取标记时识别它们。根据您使用的是 Tomcat 还是 SJSAS,执行以下操作:
不执行任何操作!我们不需要采取任何措施将 JSTL 库添加到项目的编译类路径中。这是因为 JSTL 库已经包含在应用程序服务器库中。您可以通过展开 Libraries > Sun Java System Application Server 节点验证这一点:appserv-jstl.jar 节点在 JSTL 库中定义所有的标准标记。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1658333
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。