3.2 编写用于查询信息的Servlet
在本节建立的Servlet是这个例子的核心。这个Servlet负责接收客户端的请求消息,并通过请求消息从数据库中查询相应的信息,并将查询到的信息保存在request域中,以便负责显示查询结果的JSP页面读取并显示这些信息。下面通过IDE来建立一个Servlet程序。
选中demo工程,在右键菜单中单击【New】>【Servlet】菜单项,打开【Create Servlet】 对话框,并在【Java package】文本框中输入“chapter3”,在【Class name】文本框中输入“QueryBook”,如图3.1所示。
图3.1 【Create Servlet】对话框的第一步
单击【Next >】按钮进入下一步,在这一步不需要做任何修改,再次单击【Next >】按钮进入【Create Servlet】 对话框的第三步。选中【service】复选框,并取消【Constructors from superclass】复选择,如图3.2所示。
图3.2 【Create Servlet】对话框的第三步
在进行完上面的设置后,单击【Finish】按钮建立Servlet。
在生成的QueryBook.java文件中输入如下的代码:
package chapter3;
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class QueryBook extends HttpServlet
{
// 用于处理GET、POST等HTTP请求的方法
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
try
{
// 获得queryField请求参数的值
String queryField = request.getParameter("queryField").toString();
// 获得queryText请求参数的值
String queryText = request.getParameter("queryText").toString();
// 为了解决乱码问题,必须进行编码转换
queryText = new String(queryText.getBytes("ISO-8859-1"), "UTF-8");
// 装载mysql的驱动
Class.forName("com.mysql.jdbc.Driver");
// 建立数据库连接,获得Connection对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost/mydb?characterEncoding=UTF8",
"root", "1234");
// 使用带参数的SQL语句进行查询
PreparedStatement pStmt = conn
.prepareStatement("select * from t_books where "
+ queryField + " like ?");
// 设置查询参数值
pStmt.setString(1, "%" + queryText + "%");
// 执行查询语句,并返回ResultSet对象
ResultSet rs = pStmt.executeQuery();
// 定义一个用于保存查询结果的List<String[]>对象
List<String[]> result = new java.util.ArrayList<String[]>();
// 循环处理查询结果
while (rs.next())
{
String[] row = new String[4];
row[0] = rs.getString("name");
row[1] = rs.getString("author");
row[2] = rs.getString("isbn");
row[3] = rs.getString("price");
// 将查询结果放到result对象中
result.add(row);
}
pStmt.close(); // 关闭PreparedStatement对象
conn.close(); // 关于Connection对象
// 将查询结果保存在request域中,以便在显示查询结果的JSP页面中使用
request.setAttribute("result", result);
RequestDispatcher rd = request
.getRequestDispatcher("/chapter3/result.jsp");
// 转入result.jsp页面
rd.forward(request, response);
} catch (Exception e)
{
}
}
}
在编写上面的代码时,应注意以下几点:
1. Servlet类必须从HttpServlet类及其子类继承。
2. service方法是HttpServlet类的一个方法,用来处理各种HTTP请求。关于这个方法的细节,将在第4章介绍。
3. 在本程序中仍然使用在第2章建立的mydb数据库和t_books表。
4. 在QueryBook类中读取了两个请求参数:queryField和queryText,这两请求参数分别代表查询的类别(书名、作者和ISBN)和查询的内容。其中queryField请求参数的可取值有三个:name、author和isbn,这三个值分别和数据库中的t_books表的字段相对应。这两个请求参数值将通过用于输入查询信息的JSP页面提供。
5. 在读取queryText请求参数值后,又对其进行了编码转换,这是为了解决乱码问题。由于客户端可能提交中文信息,而提交的又是UTF-8编码,因此,需要将编码以UTF-8编码格式再转换成Java的内部编码格式。关于Java的乱码问题的系列结果方案,将在后面的内容详细讲解。
6. 本程序采用了带参数的SQL语句进行查询,这样做可以有效地避免SQL注入攻击,也可提高程序的运行效率。
7. 在程序的最后,将通过RequestDispatcher转入result.jsp页面,以显示查询结果。
在本程序中所涉及到的技术,例如,转发Web资源,request域等,将在后面的章节详细介绍,在这里读者只要知道它们的功能即可。
在建立QueryBook类的同时,IDE会自动在web.xml文件中添加如下的内容:
<servlet>
<!-- 定义Servlet名字 -->
<servlet-name>QueryBook</servlet-name>
<!-- 指定Servlet的类名 -->
<servlet-class>chapter3.QueryBook</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>QueryBook</servlet-name>
<!-- 指定访问Servlet的URL -->
<url-pattern>/QueryBook</url-pattern>
</servlet-mapping>
上面的配置代码对于Servlet是必须的,其主要内容就是通过一个Servlet名将Servlet类和访问Servlet的URL联系起来。也就是说,使用上面的配置,就可以通过URL来找到与之对应的Servlet类,并执行它。