原文: http://zetcode.com/db/apachederbytutorial/tomcat/

在本章中,我们将展示如何将 Derby 与 Apache Tomcat Web 容器组合在一起。

Apache Tomcat 是 Java 编程语言的 Web 容器。 它用于服务 JSP 页面和 servlet。 可以轻松地将 Apache Tomcat 与 Derby 一起使用。 Derby 在其lib子目录中有一个derby.war文件。 该 Web 存档仅用于控制 Derby 数据库。 Tomcat 和 Derby 都是 Apache Software Foundation 的项目。

  1. $ pwd
  2. /home/janbodnar/bin/tomcat
  3. $ ls lib/derby*
  4. lib/derbyclient.jar lib/derby.jar lib/derbynet.jar

首先,我们必须将derbyclient.jarderby.jarderbynet.jar文件复制到 Tomcat 安装目录的lib子目录中。

  1. $ ls webapps
  2. derby.war docs examples host-manager manager ROOT

然后,我们必须将 derby.war 文件复制到 Tomcat 安装目录的webapps子目录文件中。 Tomcat 启动时,将解压缩并部署文件。

  1. $ export JAVA_OPTS=-Dderby.system.home=/home/janbodnar/programming/derby/dbs

当我们通过 Tomcat 启动 Derby 时,不考虑DERBY_OPTS变量。 在启动 Tomcat 和 Derby 服务器之前,必须先设置derby.system.home。 我们可以在JAVA_OPTS变量中设置 Derby 系统目录。

  1. $ bin/startup.sh
  2. Using CATALINA_BASE: /home/janbodnar/bin/tomcat
  3. Using CATALINA_HOME: /home/janbodnar/bin/tomcat
  4. Using CATALINA_TMPDIR: /home/janbodnar/bin/tomcat/temp
  5. Using JRE_HOME: /home/janbodnar/bin/jdk1.6.0_30
  6. Using CLASSPATH: /home/janbodnar/bin/tomcat/bin/bootstrap.jar:
  7. /home/janbodnar/bin/tomcat/bin/tomcat-juli.jar

使用startup.sh脚本启动 Tomcat 服务器。

使用 Derby & Apache Tomcat - 图1

图:Tomcat 启动页面

导航到localhost:8080,这是 Tomcat 监听的默认 URL,我们会看到 Tomcat 欢迎页面。

使用 Derby & Apache Tomcat - 图2

图:Derby 启动

要启动 Derby 数据库,我们导航到localhost:8080/derby/derbynet。 这将启动 Derby。 我们有几个按钮可用于启动/停止服务器,启用/禁用日志记录或跟踪。

  1. <load-on-startup>0</load-on-startup>

每次启动 Tomcat 服务器时,我们都必须导航至上述 URL。 要自动启动 Derby,我们可以在web.xml文件的<servlet>标记内添加以上行。 该文件位于webapps/derby/WEB-INF目录中。

创建测试数据库

对于那些从一开始就没有遵循教程的人,我们将再次创建testdb数据库。 我们将一个表添加到数据库中。 您可以跳过数据库和表(如果已经存在)的创建。

  1. $ cat cars.sql
  2. CREATE SCHEMA USER12;
  3. CREATE TABLE CARS(ID INT PRIMARY KEY, NAME VARCHAR(30), PRICE INT);
  4. INSERT INTO CARS VALUES(1, 'Audi', 52642);
  5. INSERT INTO CARS VALUES(2, 'Mercedes', 57127);
  6. INSERT INTO CARS VALUES(3, 'Skoda', 9000);
  7. INSERT INTO CARS VALUES(4, 'Volvo', 29000);
  8. INSERT INTO CARS VALUES(5, 'Bentley', 350000);
  9. INSERT INTO CARS VALUES(6, 'Citroen', 21000);
  10. INSERT INTO CARS VALUES(7, 'Hummer', 41400);
  11. INSERT INTO CARS VALUES(8, 'Volkswagen', 21600);

我们将需要此 SQL 文件。

  1. $ cat dbs/derby.properties
  2. derby.stream.error.logSeverityLevel=0
  3. derby.database.fullAccessUsers=user12
  4. derby.database.defaultConnectionMode=readOnlyAccess
  5. derby.connection.requireAuthentication=true
  6. derby.user.user12=34klq*
  7. derby.user.user13=33kl33
  8. derby.user.user14=14kl14
  9. derby.user.user15=35rr++
  10. derby.authentication.provider=builtin

在 Derby 系统目录中,我们有derby.properties文件。 在此文件中,我们配置一些选项。 我们将日志严重性级别设置为 0 以报告所有可能的问题。 这是在测试环境中完成的。 我们启用身份验证。 我们使用相应的密码创建四个用户。 用户 12 中只有一个拥有完全访问权限。 其他人只有readOnlyAccess

  1. $ java -Dderby.system.home=/home/janbodnar/programming/derby/dbs \
  2. -Dij.protocol=jdbc:derby: -jar $DERBY_HOME/lib/derbyrun.jar ij
  3. ij version 10.8
  4. ij>

我们启动ij命令行工具。 我们将使用它来创建数据库和表。 Derby 系统目录位于/home/janbodnar/programming/derby/dbs

  1. ij> CONNECT 'jdbc:derby://localhost:1527/testdb;create=true;
  2. user=user12;password=34klq*';

我们创建testdb数据库并连接到它。 我们提供用户凭证。

  1. ij> run 'cars.sql';

我们执行cars.sql脚本,该脚本创建CARS表并将其填充数据。

  1. ij> SELECT * FROM CARS;
  2. ID |NAME |PRICE
  3. ------------------------------------------------------
  4. 1 |Audi |52642
  5. 2 |Mercedes |57127
  6. 3 |Skoda |9000
  7. 4 |Volvo |29000
  8. 5 |Bentley |350000
  9. 6 |Citroen |21000
  10. 7 |Hummer |41400
  11. 8 |Volkswagen |21600
  12. 8 rows selected

这是我们的CARS表。 接下来,我们将创建一个 Java servlet,它将在 Web 浏览器中显示这些值。

项目

我们将创建一个简单的 Web 应用,该应用将连接到 Derby 数据库。 一个 Java Servlet 将连接到 Derby,并从CARS表中检索所有数据。

  1. $ tree
  2. .
  3. ├── build.xml
  4. ├── context.xml
  5. ├── lib
  6. └── servlet-api.jar
  7. ├── src
  8. └── zetcode
  9. └── SelectAllCars.java
  10. └── web.xml
  11. 3 directories, 5 files

在当前工作目录中,我们有一个 Ant build.xml文件,context.xml配置文件,web.xml部署描述符文件以及srclib子目录。 build.xml文件是 Ant 构建文件,它描述了构建,部署或清理项目的任务。 web.xml定义了 Web 应用的结构。 在lib目录中,有servlet-api.jar文件,用于编译源文件。 (可以在 Tomcat 安装目录的lib子目录中找到它。)在src目录中,我们有 Java 源文件。

web.xml文件定义 Web 应用的结构。

  1. <?xml version="1.0" encoding="UTF8"?>
  2. <web-app xmlns="http://java.sun.com/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  5. http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  6. version="3.0"
  7. metadata-complete="true">
  8. <description>
  9. Servlet which connects to Derby
  10. </description>
  11. <display-name>Derby, Tomcat</display-name>
  12. <servlet>
  13. <servlet-name>SelectAllCars</servlet-name>
  14. <servlet-class>zetcode.SelectAllCars</servlet-class>
  15. </servlet>
  16. <servlet-mapping>
  17. <servlet-name>SelectAllCars</servlet-name>
  18. <url-pattern>/SelectAllCars</url-pattern>
  19. </servlet-mapping>
  20. </web-app>

这些是web.xml文件的内容。 在此文件中,我们注册SelectAllCars servlet。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Context>
  3. <Resource name="jdbc/testdb"
  4. auth="Container"
  5. type="javax.sql.DataSource"
  6. username="user12"
  7. password="34klq*"
  8. driverClassName="org.apache.derby.jdbc.ClientDriver"
  9. url="jdbc:derby://localhost:1527/testdb"
  10. maxActive="10"
  11. maxIdle="4"/>
  12. </Context>

context.xml文件中,我们定义 JDBC 数据源。 可以为所有 Web 应用或单个应用定义context.xml文件。 后者是我们的情况。

我们将显示 Ant 构建文件,该文件将用于构建和部署我们的小型应用。

  1. <?xml version="1.0" ?>
  2. <project name="allcars" default="deploy">
  3. <property name="src.dir" value="src"/>
  4. <property name="build.dir" value="build"/>
  5. <property name="dist.dir" value="dist"/>
  6. <property name="deploy.dir" value="/home/janbodnar/bin/tomcat/webapps"/>
  7. <echo>${ant.project.name}</echo>
  8. <target name="init">
  9. <mkdir dir="${build.dir}/classes" />
  10. <mkdir dir="${dist.dir}"/>
  11. <echo>Directories created.</echo>
  12. </target>
  13. <target name="compile" depends="init">
  14. <javac srcdir="${src.dir}" destdir="${build.dir}/classes"
  15. includeantruntime="false">
  16. <classpath path="lib/servlet-api.jar"/>
  17. </javac>
  18. <echo>Source files compiled.</echo>
  19. </target>
  20. <target name="archive" depends="compile">
  21. <war destfile="${dist.dir}/${ant.project.name}.war" webxml="web.xml">
  22. <classes dir="${build.dir}/classes"/>
  23. <metainf file="context.xml"/>
  24. </war>
  25. <echo>Archive created.</echo>
  26. </target>
  27. <target name="deploy" depends="archive">
  28. <copy file="${dist.dir}/${ant.project.name}.war" todir="${deploy.dir}"/>
  29. <echo>Project deployed.</echo>
  30. </target>
  31. <target name="clean">
  32. <delete dir="${dist.dir}"/>
  33. <delete dir="${build.dir}"/>
  34. <echo>Project cleaned.</echo>
  35. </target>
  36. </project>

构建文件包括五个任务。 初始化任务将创建必要的目录。 编译任务将编译源代码。 存档任务将创建一个网络存档。 deploy 任务会将归档文件部署到 Tomcat 服务器。 最后,清洁任务将进行清洁。

以下是SelectAllCars Servlet。

  1. package zetcode;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.sql.Connection;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.logging.Level;
  9. import java.util.logging.Logger;
  10. import javax.naming.Context;
  11. import javax.naming.InitialContext;
  12. import javax.naming.NamingException;
  13. import javax.servlet.ServletException;
  14. import javax.servlet.http.HttpServlet;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17. import javax.sql.DataSource;
  18. public class SelectAllCars extends HttpServlet {
  19. protected void processRequest(HttpServletRequest request,
  20. HttpServletResponse response)
  21. throws ServletException, IOException {
  22. response.setContentType("text/html;charset=UTF-8");
  23. PrintWriter out = null;
  24. Connection con = null;
  25. Statement st = null;
  26. ResultSet rs = null;
  27. try {
  28. out = response.getWriter();
  29. Context ctx = new InitialContext();
  30. DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/testdb");
  31. con = ds.getConnection();
  32. st = con.createStatement();
  33. out.println("<html>");
  34. out.println("<head>");
  35. out.println("<title>SimpleServlet</title>");
  36. out.println("</head>");
  37. out.println("<body>");
  38. rs = st.executeQuery("SELECT * FROM CARS");
  39. while (rs.next()) {
  40. out.print(rs.getInt(1));
  41. out.print(" ");
  42. out.print(rs.getString(2));
  43. out.print(" ");
  44. out.print(rs.getString(3));
  45. out.print("<br>");
  46. }
  47. out.println("</body>");
  48. out.println("</html>");
  49. } catch (NamingException | SQLException ex) {
  50. Logger lgr = Logger.getLogger(SelectAllCars.class.getName());
  51. lgr.log(Level.SEVERE, ex.getMessage(), ex);
  52. } finally {
  53. try {
  54. if (rs != null) {
  55. rs.close();
  56. }
  57. if (con != null) {
  58. con.close();
  59. }
  60. if (out != null) {
  61. out.close();
  62. }
  63. } catch (SQLException ex) {
  64. Logger lgr = Logger.getLogger(SelectAllCars.class.getName());
  65. lgr.log(Level.WARNING, ex.getMessage(), ex);
  66. }
  67. }
  68. }
  69. @Override
  70. protected void doGet(HttpServletRequest request,
  71. HttpServletResponse response)
  72. throws ServletException, IOException {
  73. processRequest(request, response);
  74. }
  75. @Override
  76. protected void doPost(HttpServletRequest request,
  77. HttpServletResponse response)
  78. throws ServletException, IOException {
  79. processRequest(request, response);
  80. }
  81. }

在上面的 servlet 中,我们连接到 Derby testdb数据库并从CARS表中获取所有行。

  1. Context ctx = new InitialContext();
  2. DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/testdb");

我们使用 JNDI 命名查找来获取数据源。 从数据源,我们创建连接对象。

  1. rs = st.executeQuery("SELECT * FROM CARS");
  2. while (rs.next()) {
  3. out.print(rs.getInt(1));
  4. out.print(" ");
  5. out.print(rs.getString(2));
  6. out.print(" ");
  7. out.print(rs.getString(3));
  8. out.print("<br>");
  9. }

我们使用 SQL 语句从CARS表中检索所有数据。 我们从结果集对象中打印数据。

  1. $ ant
  2. Buildfile: /home/janbodnar/programming/derby/servlet/build.xml
  3. [echo] allcars
  4. init:
  5. [mkdir] Created dir: /home/janbodnar/programming/derby/servlet/build/classes
  6. [mkdir] Created dir: /home/janbodnar/programming/derby/servlet/dist
  7. [echo] Directories created.
  8. compile:
  9. [javac] Compiling 1 source file to /home/janbodnar/programming/derby/
  10. servlet/build/classes
  11. [echo] Source files compiled.
  12. archive:
  13. [war] Building war: /home/janbodnar/programming/derby/servlet/dist/allcars.war
  14. [echo] Archive created.
  15. deploy:
  16. [copy] Copying 1 file to /home/janbodnar/bin/tomcat/webapps
  17. [echo] Project deployed.
  18. BUILD SUCCESSFUL
  19. Total time: 1 second

我们启动 ant 来构建和部署项目。

使用 Derby & Apache Tomcat - 图3

图:SelectAllCars servlet 的输出

我们导航到localhost:8080/allcars/SelectAllCars URL 并接收输出。

在本章中,我们使用了 Derby 和 Apache Tomcat。